... | ... | @@ -416,13 +416,15 @@ We were tweaking the robot both in construction and program implementation up to |
|
|
|
|
|
The most important next behavior we would have looked at implementing was some kind of *searchEnemy* behavior, as a possible replacement for our base *Drive* behavior. Since our robot currently would just drive straight until hitting a white edge, and if our opponent happens to be in front of it, charge at it, it would be a vast improvement if the robot could actively search for our opponent itself, rather than hoping to bump into it randomly. A very basic way we considered doing this was to simply have the robot spin around on the spot, until it found the opponent with the ultrasonic sensor, in which case *PursueEnemy* would take over. Alternatively, we could have changed our *Drive* behavior to not just drive straight, but drive around in some random fashion. This would have also been made much easier, had we been able to get our **_MotivatedBumperCar_** to work, as it would have allowed us to, for example, have a *Turn* behavior that would randomly get higher motivation than *Drive*.
|
|
|
|
|
|
We also still had one sensor port available, which could have been used for a single touch sensor bumper somewhere, perhaps in the back as an input for a defensive behavior when being shoved from behind. Another use for the sensor port could be another UltraSonic sensor, which would would enable binocular vision and make it a lot easier to locate an enemy. A problem with just one UltraSonic sensor is that we risk picking up on enemies in either side of our periphery and speed up driving away from him, where we could take advantage of 2 sensors by knowing their relative position. The tournament winner Hans took advantage of this mechanism.
|
|
|
We also still had one sensor port available, which could have been used for a single touch sensor bumper somewhere, perhaps in the back as an input for a defensive behavior when being shoved from behind. Another use for the sensor port could be another UltraSonic sensor, which would would enable binocular vision and make it a lot easier to locate an enemy. A problem with just one UltraSonic sensor was that we risked picking up on enemies in either side of our periphery and speed up driving away from him, where we could take advantage of 2 sensors by knowing their relative position. The tournament winner Hans took advantage of this mechanism.
|
|
|
|
|
|
As far as the bumper goes, we also initially considered making a purely defensive robot using two bumpers on each side of the robot, and then attempt to win with defensive maneuvers reacting to which side we’d get shoved from. We ended up deciding that this would be a lot more difficult to implement cleverly, and also an incredibly obnoxious strategy for the other competitors to fight against, so we never ran with it. However, after seeing the tournament battles and how often some robots would lose due to shoving their opponent to the edge, and then the attacked robot would turn around (from seeing the white edge), and drag the attacking robot off the edge as a result, we realized that a defensive strategy of sorts might not have been a bad idea.
|
|
|
|
|
|
#### Problems
|
|
|
|
|
|
In addition to not getting to implement all the behaviors we would have liked, we also didn’t have time to properly debug our current ones. All our behaviors worked individually, and when running our SumoBot, they also all seemed to work initially… Until a couple had activated, in which case it seemed both *PursueEnemy* and *FlipEnemy* would stop ever taking control, which would indicate something went wrong with our *Updater*, as these two behaviors relied on readings from the ultrasonic sensor. A problem we considered was having a different Updater in each thread, which could mean that the updaters competed, due to the amount of downtime there is in the ultrasonic sensor. This problem can be seen in video 2, where the *FlipEnemy* triggers correctly initially, but then ceases to function after hitting the white edge, although the robot continues to drive around and dodge the edges.
|
|
|
In addition to not getting to implement all the behaviors we would have liked, we also didn’t have time to properly debug our current ones. All our behaviors worked individually, and when running our SumoBot, they also all seemed to work initially… Until the behavior had switched a couple of times, after which it seemed both *PursueEnemy* and *FlipEnemy* would stop ever taking control, which would indicate something went wrong with our *Updater*, as these two behaviors relied on readings from the ultrasonic sensor. This problem can be seen in video 2, where the *FlipEnemy* triggers correctly initially, but then ceases to function after hitting the white edge, although the robot continues to drive around and dodge the edges.
|
|
|
|
|
|
A solution we considered was having a different Updater in each thread, however that could mean that the updaters competed with each other for the sensor, due to downtime in the ultrasonic sensor when pinging it.
|
|
|
|
|
|
[![Behavior problems](http://img.youtube.com/vi/1-54uEO9aJc/0.jpg)](https://www.youtube.com/watch?v=1-54uEO9aJc)
|
|
|
|
... | ... | @@ -438,56 +440,9 @@ Our sumo wrestler managed a solid 4th place in our group in the tournament with |
|
|
|
|
|
Two of our battles ended in a tie, as a result of the two robots getting stuck in each other trying to drive forward, but getting nowhere. After seeing this, we realized it would have been a good idea to possibly include some sort of trigger in one of our behaviors in case too long time had passed since some event had happened (such as seeing a white edge), and then try to back up slightly, as this could have possibly prevented the stalemates.
|
|
|
|
|
|
#### Implementation
|
|
|
|
|
|
Done:
|
|
|
|
|
|
* implemented AvoidEdge behavior (motivation 100 on detection of edge)
|
|
|
|
|
|
* our own arbitrator and motivatedcar do not work - we use Ole’s and see if we have time to figure out what’s wrong with our own implementation later
|
|
|
|
|
|
* robot turns too much (values -360 for one wheel, -1300 for other wheel); sometimes drives backwards off edge
|
|
|
|
|
|
* → implementation that turns on the spot. Works OK. Will optimize later if desired.
|
|
|
|
|
|
* Next: Implement detection of other robot and go to it. After that: Implement detection of other robot and try to flip it.
|
|
|
|
|
|
* On detection and following of other robot:
|
|
|
|
|
|
* How to test? Make robot go faster if it sees an enemy - that way we can tell that it has detected its enemy. Implement behavior Drive that only drives with speed 60 - makes it very obvious when the robot switches to PursueEnemy (where we set speed to 400)
|
|
|
|
|
|
* Don’t try to make it follow the enemy - simply go faster straight ahead if enemy is within vision
|
|
|
|
|
|
* Overvejelse: We let avoiding the edge outweigh enemy detection, as crossing of the edge leads to losing the match with much higher certainty than not pursuing an enemy. Perhaps we should even stop for a second when losing track of the enemy, so as to minimize the risk of being lured to the edge (or would stopping make us more vulnerable to attacks?).
|
|
|
|
|
|
* Using distance 30 cm for detection; have not tested other distances
|
|
|
|
|
|
* On detection and flipping other robot
|
|
|
|
|
|
* Change base speed to 200
|
|
|
|
|
|
* Use tacho counter to make sure that we don’t flip forklift "all over the place" like when Frej was almost strangled in a previous lesson
|
|
|
|
|
|
* Make test program for testing flip: FlipTest
|
|
|
|
|
|
* NB: Robot must not begin to chase because it is seeing its own forklift (should not happen, as pursue has lower priority)
|
|
|
|
|
|
* First test: -30 rotation on flip motor (motorport A, FlipMotor). Looks okay.
|
|
|
|
|
|
* Note: Use of motivation functions would be nice: Could lower motivation for flipping after a flip has been performed, such that the robot would rather push the other robot by running into it again
|
|
|
|
|
|
* Implement so that on suppress or loss of sight of enemy makes the forklift go back down
|
|
|
|
|
|
* Sometimes robot sees (bogus?) far distances even if something is very close in front of it → forklift flips out [VIDEO]
|
|
|
|
|
|
* → make update thread to keep track of distance over a timeslice
|
|
|
DIT NOT WORK OUT!
|
|
|
|
|
|
* Note: Can FlipEnemy be suppressed in between setting ForkLifted to true and flipping the fork? What happens then?
|
|
|
|
|
|
#### Attempted solution to ForkLift behavior
|
|
|
|
|
|
When we decided to hardcode the forklift behavior, we had already considered other solutions, one of which was to sample over an amount of time and take the minimum reading as the distance we compared with the trigger. We had some initial problems libraries we wanted to utilize for this solution, so it wasn’t ready for the tournament, but in the end we had something close to a proof-of-concept. This solution also tried to solve the competition over the ultrasonic sensor by making the updater (and sampler) shared between the behaviors. The PursuitEnemy didn’t need the sampling over time, but it didn’t really harm the behavior either - it would be quite easy to solve this though. The only tests we had time to run used a FIFO queue of 50 samples and used the smallest distance in the getDistance() method. Since the UltraSonic sensor has a downtime of around 20ms, this means that the queue has approximately a second worth of samples at all times (except for this first second where the queue is being filled). This meant that a reading of distance <10 would be in effect for a whole second, which is way more than it should. Further testing would have allowed us to calibrate these sampling parameters though. There isn’t any delay to this method though, since it updates the currently smallest distance after every ultrasonic ping. The current version of this solution can be found in **_SharedThreadSumoBot.java_**.
|
|
|
When we decided to hardcode the forklift behavior, we had already considered other solutions, one of which was to sample over an amount of time and take the minimum reading as the distance we compared with the trigger. We had some initial problems with the libraries we wanted to utilize for this solution, so it wasn’t ready for the tournament, but in the end we had something close to a proof-of-concept. This solution also tried to solve the competition over the ultrasonic sensor by making the *Updater *(and sampler) shared between the behaviors. The PursueEnemy didn’t need the sampling over time, but it didn’t really harm the behavior either - it would be quite easy to solve this though. The only tests we had time to run used a FIFO queue of 50 samples and used the smallest distance in the getDistance() method. Since the UltraSonic sensor has a downtime of around 20ms, this means that the queue has approximately a second worth of samples at all times (except for this first second where the queue is being filled). This meant that a reading of distance <10 would be in effect for a whole second, which is way more than it should. Further testing would have allowed us to calibrate these sampling parameters though. There isn’t any delay to this method though, since it updates the currently smallest distance after every ultrasonic ping. The current version of this solution can be found in **_SharedThreadSumoBot.java_**.
|
|
|
|
|
|
## **Conclusion**
|
|
|
|
... | ... | @@ -519,3 +474,9 @@ Even though we thought that this lab session looked pretty structured and we the |
|
|
|
|
|
[10] Ole Caprani’s implementation of [BumperCar.java](http://legolab.cs.au.dk/DigitalControl.dir/NXT/Lesson9.dir/BumperCar.java)
|
|
|
|
|
|
[11] [Video 1](https://www.youtube.com/watch?v=lLlhimXuy6I)
|
|
|
|
|
|
[12] [Video 2](https://www.youtube.com/watch?v=1-54uEO9aJc)
|
|
|
|
|
|
[13] [Video 3](https://www.youtube.com/watch?v=70-1zJPpsRc)
|
|
|
|