<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9032316157388116048</id><updated>2011-10-28T11:22:05.056-07:00</updated><title type='text'>LÆGØLÅB-IT</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>zimba</name><uri>http://www.blogger.com/profile/05249586150135171428</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-7804695442805294244</id><published>2008-01-16T02:39:00.000-08:00</published><updated>2008-01-24T07:10:36.770-08:00</updated><title type='text'>End Course Project - 2nd robot, map building, ..., 3rd sound sensor...END!</title><content type='html'>&lt;hr /&gt;Date: 16.01.2008&lt;br /&gt;Duration of activity: 4 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Goal&lt;/span&gt;: finish the last details and set up the presentation for tomorrow&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Plan&lt;/span&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;build an exact copy of the robot;&lt;/li&gt;&lt;li&gt;implement and debug MapBuilding;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;test the communication between the two robots;&lt;/li&gt;&lt;li&gt;prepare a demo-show for the presentation.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;After we have retrieved all the Lego bricks (borrowing from everyone the missing pieces), in less than an hour we succeeded in cloning our robot.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158375378943565794"&gt;&lt;img src="http://lh3.google.it/djjeck/R5Y7E7ANX-I/AAAAAAAAA58/dGeWQQqcAts/s144/IMG_4270.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration: underline;"&gt;MapBuilding&lt;/span&gt;&lt;br /&gt;In our idea every robot has to keep the positions of all the party that it visited.&lt;br /&gt;Every party can be considered just a couple &lt;span style="font-style: italic;"&gt;(x, y)&lt;/span&gt; in the absolute coordinates system. We implemented this idea as an instance of the class &lt;a href="http://www.daimi.au.dk/%7Ecosenal/legolab/Location.java"&gt;Localization&lt;/a&gt;.&lt;br /&gt;A map is then simply a list of these locations.&lt;br /&gt;The problem of building the map is strictly connected with that of communicating the position of the party discovered.&lt;br /&gt;This allowed us to merge the implementation of the management of the Bluetooth connection and the building of the map in the same class.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Subplan&lt;/span&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;add a 3rd sound sensor on the rear of the car&lt;br /&gt;&lt;/li&gt;&lt;li&gt;test if this modification improves the performance&lt;/li&gt;&lt;/ul&gt;&lt;span style="text-decoration: underline;"&gt;3rd Sound Sensor&lt;/span&gt;&lt;br /&gt;We noticed that sometimes our robot behaves in an unwanted way. When the robot is directed on the opposite side of the sound source, and close to a wall, while trying turning it would see the wall with the ultrasonic sensor, and avoid that continuously, while actually going far from the sound source.&lt;br /&gt;We thought that we could avoid the problem by putting a third sound sensor on the robot's back, and using it only when there is a sensible difference between front sensors and rear sensor readings.&lt;br /&gt;&lt;br /&gt;We implemented a new behavior, called Party Behind, which is connected to the Sound Perceiver as input, and is activated only when a sound source can be heard from behind the robot louder than on front.&lt;br /&gt;We had then to had some more tricks to add. We previously had moved motors in the back of the robot in order to reduce noise on sensors. By putting a sound sensor on the back we made the robot continuously spin.&lt;br /&gt;We then tried increasing the threshold needed between front and read sensors, but in this case, when the robot was going slowly, this behavior didn't work.&lt;br /&gt;Then, as final solution, we added a trick inside the Sound Perceiver class. The Sound Perceiver class queries motors to know if they are moving or not. If they are, a fixed value is subtracted from rear sensor, otherwise not.&lt;br /&gt;This is not an accurate solution, and therefore we couldn't use that for front sensor, that need to be accurate, but we decided to keep it for this experimental behavior.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5159056483591950290"&gt;&lt;img src="http://lh6.google.it/djjeck/R5imibisj9I/AAAAAAAABBM/F-wwfgT8Siw/s288/IMG_4316.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;:&lt;br /&gt;The Party Locating capability of our robots is ok, although it works better only for some kinds of sound.&lt;br /&gt;We completed a working prototype of our original idea, but we still miss some details.&lt;br /&gt;We should have worked more on motivations, to make robots less deterministic, and we should have tested the behavior of a big flock, but we didn't have time to test (and request enough NXTs).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;File&lt;/span&gt; (all the project - under license GPL3):&lt;a href="http://www.daimi.au.dk/%7Ecosenal/legolab/PartyRobotsProject.rar"&gt;&lt;br /&gt;PartyRobotsProject.rar&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-7804695442805294244?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/7804695442805294244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=7804695442805294244' title='42 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/7804695442805294244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/7804695442805294244'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2008/01/end-course-project-2nd-robot-map.html' title='End Course Project - 2nd robot, map building, ..., 3rd sound sensor...END!'/><author><name>zimba</name><uri>http://www.blogger.com/profile/05249586150135171428</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>42</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-544098600879366422</id><published>2008-01-13T03:15:00.000-08:00</published><updated>2008-01-24T06:16:57.403-08:00</updated><title type='text'>End Course Project - Software Design</title><content type='html'>&lt;hr&gt;Date: 13.01.2008&lt;br /&gt;Duration of activity: 6 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;At this point we completed testing and implementing almost every small component for our robot. We then tried to put everything together.&lt;br /&gt;We had already agreed on a motivation-based architecture, because we want our robot to have different behaviors, depending on its wills (i.e. internal states, motivations).&lt;br /&gt;We had still to define implementation details. We discussed many points, and we summarize here our final decisions and their motivations.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Architecture discussion&lt;/font&gt;&lt;br /&gt;We defined four behaviors, which can be seen in the chart below, in a subsumption style.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158392026236805154"&gt;&lt;img src="http://lh3.google.it/djjeck/R5ZKN7ANYCI/AAAAAAAAA68/_4EuBL3ABgM/s400/subsumption.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Modules:&lt;/font&gt;&lt;br /&gt;Each of those four behaviors gives its output to the Navigator, which is an adapter class for motors.&lt;br /&gt;&lt;br /&gt;The lowest priority behavior is Party Searcher: its responsibility is to drive the robot toward the nearest sound source. We will use the Braitenberg strategy, already implemented and tested in previous sessions. It only receives input from Sound Sensors.&lt;br /&gt;&lt;br /&gt;The second behavior is Party Reacher: it drives the robot toward a known sound source, when a new source is received from other agents. It receives locations from incoming bluetooth communications.&lt;br /&gt;&lt;br /&gt;The third behavior is Avoider: it makes the robot go back when encounters some obstacle, helping it keeping track of its position. It uses the Ultrasonic Sensor.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158374129108082626"&gt;&lt;img src="http://lh4.google.it/djjeck/R5Y58LANX8I/AAAAAAAAA5k/0ZpbRi4FHgQ/s144/IMG_4247.JPG"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The highest priority behavior is At The Party: it is activated only when the robot is close to a sound source, hence it uses the Sound Sensors and some sound level threshold. It acts by stopping the robot and communicating its coordinates to any other robot in range for a bluetooth communication.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Suppression order:&lt;/font&gt;&lt;br /&gt;The Party Reacher behavior must have higher priority than the Party Searcher behavior, because if some party location is already known and not visited, there is no need for wandering and looking for sound.&lt;br /&gt;&lt;br /&gt;The Avoider behavior has higher priority than the Party Searcher and Party Reacher behaviors, since when moving, the robot must always be careful about obstacles, in order to keep track of its position.&lt;br /&gt;When stopped inside a party, instead, it is better it remains stopped, in order to avoid losing the party position. In addition to this, the only cause of the avoider detecting some obstacle when stopped inside a party is when new robots arrive to the same party. It will be other robots' responsibility to not hit the stopped robots.&lt;br /&gt;&lt;br /&gt;The At The Party behavior must have a priority higher than the one of the Party Searcher behavior, to obviously stop the search when successful. It also must be higher of the Party Reacher behavior priority, because even if the party where the Party Reacher is leading the robot is not perfectly reached, and the At The Party behavior recognizes the sound level of a party, it could only be because of some error in Navigation class; if the reasonable sound threshold is reached while driving to some known party coordinates, instead, there is no need to continue going toward the specified location.&lt;br /&gt;&lt;br /&gt;As already specified in previous lab sessions, Navigator class we will use is similar to the one from lejos packages, being able of keep track of robot position, but it accepts motor powers as input, instead of simple coordinates, in order to work with our Braitenberg-like sound follower.&lt;br /&gt;&lt;br /&gt;In addition to those modules, a Map must be implemented, which is basically a collection of landmarks (in this case party locations) to remember, and some helper methods.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Motivations&lt;/span&gt;&lt;br /&gt;As pointed out before, we want our robot to have a motivation based architecture. In the discussion above the architecture seems to be working and functional only using a simple subsumption architecture. Why do we want then to use motivation functions, instead of simple boolean activation?&lt;br /&gt;What we want to obtain is the behavior of an artificial creature, so we want the motivations be conditioned by some internal state. But after defining the agents' behaviors, we noticed that those four behaviors are not concurrent, in their simple interpretation, but they must be in that precise order, to work coherently.&lt;br /&gt;&lt;br /&gt;The idea of building a flock of agents that locates parties must then be explained. It is true that an agent which locates sound must follow a precise deterministic strategy, in order to get to one of its goals. But then, when some party locations are known to the flock, and when many robots are inside a sound source, then a complex flock behavior can be imagined.&lt;br /&gt;After having found a sound source, agents could evaluate their motivation of remaining at that party according to&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the number of mates in the same party and their personal willing of be in company&lt;/li&gt;&lt;li&gt;the time of having been stopped and their personal willing of walking a bit&lt;/li&gt;&lt;li&gt;the time spent and the music volume of that party and their personal willing of listening to music&lt;/li&gt;&lt;li&gt;the kind of music of that party and their personal taste in music (although we already decided that the capability of recognizing some features of a sound is too hard to implement).&lt;/li&gt;&lt;/ul&gt;In addition to this, not only behavior arbitration could be affected by internal motivations, but also the intensity of behavior actions.&lt;br /&gt;If some agent has a low motivation for walking, it could wander slowly, or stop, even if it is not inside a party.&lt;br /&gt;If some agent has an high willing of listening to music, it could low down the party sound threshold, or speed up motors, in order to more easily end up listening to some music.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then, although a simple subsumption architecture could be enough for our project, this is why we chose to implement behaviors with motivation functions: we want our architecture to be scalable to further experiments.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Data flow&lt;/span&gt;&lt;br /&gt;The diagram below can illustrate better data flows between modules.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158391781423669234"&gt;&lt;img src="http://lh6.google.it/djjeck/R5ZJ_rANX_I/AAAAAAAAA6k/BLgSQZgNBec/s400/diagram.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Modules are the same as in the previous diagram. Arrows show directions of data flow.&lt;br /&gt;This layout helps to see how inter-agents communication works.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;First part of the communication - an agent founds a party:&lt;/font&gt;&lt;br /&gt;When the "At The Party" behavior receives from Sound Perceiver (an adapter for two sound sensors) a sound level over some threshold, the robot knows it is in the range of a party. Then it tells Navigator to stop, and saves current location inside the Map. The map, then, automatically notifies the Communicator module, which broadcasts the new location to any other agent around.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Second part of the communication - an agent receives a party location:&lt;/font&gt;&lt;br /&gt;When a Communicator module of some agent receives an incoming communication about some party location, it sends it into the Map.&lt;br /&gt;The Party Reacher behavior, which polls the Map, will notice the new landmark added by some external agent, and will communicate those coordinates to Navigator module, which will drive up to that location.&lt;br /&gt;When arrived to the location, Party Reacher will lose its motivation, and Party Searcher will do the rest of the job to correct possible errors in position tracking, up to when the At The Party behavior will detect a party.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We proceeded then implementing (or adapting some older classes) the most of the discussed architecture, and we left debugging and testing to the following day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-544098600879366422?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/544098600879366422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=544098600879366422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/544098600879366422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/544098600879366422'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2008/01/end-course-project-software-design.html' title='End Course Project - Software Design'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-1093929766837341309</id><published>2008-01-11T10:32:00.000-08:00</published><updated>2008-01-24T06:16:10.216-08:00</updated><title type='text'>End Course Project - Location saving</title><content type='html'>&lt;hr /&gt;Date: 11.01.2008&lt;br /&gt;Duration of activity: 5 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Goal&lt;/span&gt;: &lt;span class="postbody"&gt;Make the robot able to describe, &lt;/span&gt;&lt;span class="postbody"&gt;in a two dimensional system, &lt;/span&gt;&lt;span class="postbody"&gt;the location of the party where it is "dancing".&lt;br /&gt;&lt;/span&gt;&lt;span class="postbody"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Plan&lt;/span&gt;:&lt;/span&gt;&lt;span class="postbody"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;figure out how to use the tachometer of the NXT motors;&lt;/li&gt;&lt;li&gt;understand how TachoNavigator works;&lt;/li&gt;&lt;li&gt;implement a specific Navigator to make the robot move "according to Braitenberg" and localize the resulting position;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;add a function to make the robot go in a specific position in the map.&lt;/li&gt;&lt;li&gt;test the accuracy of our Navigator&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="text-decoration: underline;"&gt;leJOS API&lt;/span&gt;&lt;br /&gt;&lt;span&gt;The only tool we can use to determine the distance covered and the direction of the robot is the tachometer included in the NXT Motors. The leJOS API provides the interface Tachometer (implemented by MotorPort) to interact with it, containing these methods:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;getTachoCount()&lt;/span&gt; - returns the rotation count of the wheel connected with the motor in degrees [0-360[&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;resetTachoCount() &lt;/span&gt;- resets the tachometer count to 0;&lt;/li&gt;&lt;/ul&gt;The class TachoNavigator allows the robot to travel in a specified position or along a specified distance or to rotate of a specific angle and keep track of the position: the values are updated after every movement is complete.&lt;br /&gt;&lt;br /&gt;The central idea of this lab session is to merge the concepts of "navigation" and "Braitenberg movement": using the Navigator API provided by leJOS the only way to make the robot move is imposing the distance or the angle that the robot has to drive.  On the contrary we need that the robot remembers its position after a movement imposed just setting the speeds of the motors and the driving time.&lt;br /&gt;&lt;br /&gt;The prototype of our "BraitenbergNavigator" consists of the following methods:&lt;br /&gt;&lt;pre&gt;public void driveArc(int speedL, int speedR);&lt;br /&gt;public void stop();&lt;br /&gt;public float getX();&lt;br /&gt;public float getY();&lt;br /&gt;public float getAngle();&lt;br /&gt;&lt;/pre&gt;The first one will be the core of the class that we are going to implement: it asks the robot to move along an arc just imposing to it the speeds of the motors and to keep track of its position. This is the main difference with the leJOS TachoNavigator and the reason why we are going to rewrite it.&lt;br /&gt;The second method interrupts the movement of the robot and updates its position.&lt;br /&gt;The last three trivial methods return in every moment the position and the direction of the robot.&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration: underline;"&gt;Implementation&lt;/span&gt;&lt;br /&gt;The driveArc method sets the speed of the motors as requested from the caller and imposes them a forward movement. Since the speeds requested as input can be negative values and the function &lt;span style="font-style: italic;"&gt;setSpeed&lt;/span&gt; doesn't accept any negative values, we just flip the sign of the speed before passing it to the motor and use the method &lt;span style="font-style: italic;"&gt;backward()&lt;/span&gt; to impose the movement.&lt;br /&gt;When the stop function is invoked, the motors are stopped and the position of the robot is updated.&lt;br /&gt;&lt;br /&gt;Therefore the core of the new class is the function &lt;span style="font-style: italic;"&gt;updatePosition(). &lt;/span&gt;The aim of this method is to calculate the coordinate of the arrival position of the robot after it covered a bend.&lt;br /&gt;The values &lt;span style="font-style: italic;"&gt;t1, t2 &lt;/span&gt;in the code and in the picture below are the distances covered by the two wheels calculated from the values returned by getTachoCount() multiplied by the known diameter of the wheels. &lt;br /&gt;&lt;pre&gt; t1 = motorLeft.getTachoCount() * wheel_diameter / 2;&lt;/pre&gt;&lt;br /&gt;Because the distance beetween the wheel is also known, it's easy to calculate the angle and the radius of the circumference which the robot is driving on.&lt;br /&gt;&lt;pre&gt; &lt;br /&gt;alpha = (t1 - t2) / wheel_distance;&lt;br /&gt;r = (t1 + t2) / (2 * alpha);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Thanks to trigonometric functions we obtain the distance covered on the axes, relative to the starting position. &lt;br /&gt;&lt;pre&gt; &lt;br /&gt;relative_y = r * Math.sin(alpha);&lt;br /&gt;relative_x = r * (1 - Math.cos(alpha));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A rotation and a translation are sufficient to obtain the new position on the absolute coordinate system.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158766972731428594"&gt;&lt;img src="http://lh6.google.it/djjeck/R5efOrisjvI/AAAAAAAAA8o/OrLJoChIrYI/s800/IMG_4314.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The next step is to add a method&lt;br /&gt;&lt;pre&gt;public void goTo(float newX, float newY)&lt;br /&gt;&lt;/pre&gt;that makes the robot move to a position indicated by the absolute coordinates &lt;span style="font-style: italic;"&gt;newY&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;newX&lt;/span&gt;.&lt;br /&gt;We  tried to implement this function using the corresponding one provided by leJOS Navigator: instancing a "normal" Navigator in the constructor of "our" navigator, resetting its position every time we call our &lt;span style="font-style: italic;"&gt;goTo&lt;/span&gt; method and calling its &lt;span style="font-style: italic;"&gt;goTo &lt;/span&gt;method with the position updated.&lt;br /&gt;An easy test,&lt;br /&gt;&lt;pre&gt;ournavigator.drawArc(300, 500);&lt;br /&gt;Thread.sleep(2000);&lt;br /&gt;ournavigator.stop();&lt;br /&gt;ournavigator.goTo(0, 0);&lt;br /&gt;&lt;/pre&gt;, discloses some mistake on the code of the &lt;span style="font-style: italic;"&gt;goTo &lt;/span&gt;method: the travelled distance is correct, but the car is driving in a wrong direction. It reveals that the coordinate systems of the two Navigators are not compatible. We think about two solutions which can resolve the problem:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;convert the coordinate system of the new navigator to those of the old one (it seems that the angle is rotated of 90°);&lt;/li&gt;&lt;li&gt;rewrite enterly the code of our goTo without using the "old" Navigator.&lt;/li&gt;&lt;/ol&gt;We chose the second option after an observation: using the TachoNavigator.goTo inside our goTo, if the thread is interrupted during the execution of the latter, the position are not updated. We get the inspiration from the source code of TachoNavigator to rewrite our goTo and the resulting code is the following:&lt;br /&gt;&lt;pre&gt;definitiveUpdatePosition();&lt;br /&gt;rotate(angleTo(getX(), getY(), newX, newY) - getAngle());&lt;br /&gt;float distance = distanceTo(getX(), getY(), newX, newY); // cm&lt;br /&gt;int speed = 500;&lt;br /&gt;driveForward(speed); // degrees per second&lt;br /&gt;Thread.sleep((int) (1000 * cmToDegrees(distance) / speed)); // milliseconds&lt;br /&gt;stop();&lt;br /&gt;&lt;/pre&gt;where &lt;span style="font-style: italic;"&gt;rotate&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;driveForward&lt;/span&gt; are written using our coordinate system, thus we resolved also the first problem.&lt;br /&gt;&lt;br /&gt;Files:&lt;br /&gt;&lt;a href="http://www.daimi.au.dk/%7Ecosenal/legolab/BraitenbergNavigator.java"&gt;BraitenbergNavigator.java&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;:&lt;br /&gt;At the end of this session we have at our disposal a shiny navigator that can be used to move the robot indicating just the speeds of the motors and the travelling time.&lt;br /&gt;Simple tests like that one described above proved that the error is &amp;lt;10 cm out of a distance of 200 cm: we think this accuracy will be sufficient for our purposes, because it's important that     the robot goes in the proximity of the party and not exactly in the same position of the other robots.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Further development&lt;/b&gt;&lt;br /&gt;Adapt the coordinate system to that one used in standard leJOS API.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;leJOS API  (particularly the section about Motors and Tachometer) - http://lejos.sourceforge.net/p_technologies/nxt/nxj/api/lejos/nxt/Tachometer.html&lt;/li&gt;&lt;li&gt;Brian Bagnall, Maximum LEGO NXT - Building Robots with Java Brains (Chapter 12 - Localization)&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-1093929766837341309?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/1093929766837341309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=1093929766837341309' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/1093929766837341309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/1093929766837341309'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2008/01/end-course-project-location-saving.html' title='End Course Project - Location saving'/><author><name>zimba</name><uri>http://www.blogger.com/profile/05249586150135171428</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-598901304920741925</id><published>2007-12-16T04:31:00.000-08:00</published><updated>2008-01-24T06:39:41.569-08:00</updated><title type='text'>End Course Project - Sound follower</title><content type='html'>&lt;hr /&gt;Date: 16.12.2007&lt;br /&gt;Duration of activity: 8 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;hr /&gt;&lt;span style="font-weight: bold;"&gt;Plan of the day:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Design and build a prototype of sound follower robot.&lt;/li&gt;&lt;li&gt;Test the effectiveness of its implementation&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Test sound sensor capability of working in presence of multiple sound sources.&lt;/li&gt;&lt;/ul&gt;In this session we must build an important part of our project, the component which will drive the robot toward sound sources.&lt;br /&gt;We considered different options, similar to the ones met within the course.&lt;br /&gt;Among those, we considered of using a single sound sensor per agent and making the robot periodically stop and rotate 360° to sample around and choose the direction to follow.&lt;br /&gt;We also thought of using two sound sensors, and interpolating their readings, estimate the direction from which the sound could come.&lt;br /&gt;&lt;br /&gt;As a first try, we chose to implement a simple robot similar to the Braitenberg's vehicle, which uses sound sensors as inputs; we made this choice because, as we have seen during the course, this model seems to be the simplest and better working model for moving according to some kind of input.&lt;br /&gt;As Braitenberg states: "Braitenberg's vehicles consist of the simplest sort of wheeled robots in which sensors that are sensitive to different stimuli are wired directly to motors that drive the wheels".&lt;br /&gt;Valentino Braitenberg also makes an important comment, that we must be aware of: "In these models, we assume that the sensor generates a signal that is proportional to the stimulus".&lt;br /&gt;As said in previous posts, we experimented that within some range of frequencies the sound level is almost proportional to distance of sound sources.&lt;br /&gt;&lt;br /&gt;In Braitenberg's model we must connect sensor outputs to motor inputs, but before of doing that, sensor readings must be normalized with some function.&lt;br /&gt;We defined the following normalizing function:&lt;br /&gt;&lt;pre&gt;public int normalize(int value) {&lt;br /&gt;   final int MIN_VALUE = 0;&lt;br /&gt;   final int MAX_VALUE = Utils.LOUD_VALUE;&lt;br /&gt;&lt;br /&gt;   value = Math.min(MAX_VALUE, Math.max(MIN_VALUE, value));&lt;br /&gt;&lt;br /&gt;   return Math.max(0, Math.min(MAX_SPEED, (value - MIN_VALUE)&lt;br /&gt;  * MAX_SPEED / (MAX_VALUE - MIN_VALUE)));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This function implements a linear mapping between two ranges, the first related to sound values [MIN_VALUE, MAX_VALUE] and the second to motor speeds [0, MAX_SPEED].&lt;br /&gt;&lt;br /&gt;where:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;MIN_VALUE represents a threshold value for ambient noise, in this case 0.&lt;/li&gt;&lt;li&gt;MAX_VALUE represents the threshold for loud sounds. Like said in previous post, the value we used is around 70. Everything above that threshold must be considered equal.&lt;/li&gt;&lt;li&gt;MAX_SPEED represents the maximum speed that we want the robot's motors to have.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;We built a simple robot with two sound sensors and two motors and we tried the above software.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158373454798217138"&gt;&lt;img src="http://lh3.google.it/djjeck/R5Y5U7ANX7I/AAAAAAAAA5E/RjYmqPRZ67w/s144/IMG_3950.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;We spent a lot of time to test, but the robot only went straight, with some random steering.&lt;br /&gt;We tried changing some implementation detail, but, after a deeper analysis, we identified (at least) two major problems:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The robot always went forward. It was because the difference between the sound sensors readings was too small, compared to the difference between motor powers needed to steer toward the sound.&lt;/li&gt;&lt;li&gt;The robot always drove, even when there was no sound. It was because of the motors' noise.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;As solution to the first problem we decided to amplify the difference between the two readings, in order to make the vehicle more sensible on sound sensor's values.&lt;br /&gt;We then added twice the difference between the two readings to the maximum of the two values, obtaining a difference three times larger than it was.&lt;br /&gt;&lt;br /&gt;About the second problem, we noticed that the motors were too close to the sound sensors, as it can be seen from the same photo as above.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158373454798217138"&gt;&lt;img src="http://lh3.google.it/djjeck/R5Y5U7ANX7I/AAAAAAAAA5E/RjYmqPRZ67w/s144/IMG_3950.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As partial solution to this problem, we decided to move motors, trying to put them as far as possible from the sound sensors, to reduce their noise.&lt;br /&gt;&lt;br /&gt;After having rebuilt our robot, and updated the code several times, we got a robot able to go toward sound.&lt;br /&gt;We then performed some tests on it.&lt;br /&gt;&lt;br /&gt;We tried at first with beeps played by old RCX bricks, but they were basically too quiet, and weren't heard from this robot.&lt;br /&gt;We then tried with the frequencies we established with previous tests. Robot didn't seem to react as expected.&lt;br /&gt;But when trying with those frequencies, we noticed that the robot rather followed our voices, instead of pure frequencies generated by our laptops.&lt;br /&gt;&lt;br /&gt;We started then some tests on music, and we got better results, because of their wide range of frequencies. We also noticed that songs with electric guitars worked even better. This can be explained by the fact that the overdrive effect on guitar makes the sound wave squared,  which spreads the energy of the sound among more frequencies.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;We obtained good results and we are happy with that, we will proceed in this direction.&lt;br /&gt;Next time we will try to plug into the robot some location saving capability.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;&lt;br /&gt;Tom Dean, Introduction to Machina Speculatrix and Braitenberg Vehicles&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-598901304920741925?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/598901304920741925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=598901304920741925' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/598901304920741925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/598901304920741925'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2008/01/sound-follower_24.html' title='End Course Project - Sound follower'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-607083601820029361</id><published>2007-12-13T11:53:00.000-08:00</published><updated>2008-01-24T06:18:48.257-08:00</updated><title type='text'>End Course Project - Sound sensor general tests 2</title><content type='html'>&lt;hr /&gt;Date: 13.12.2007&lt;br /&gt;Duration of activity: 4 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;hr /&gt;&lt;span style="font-weight: bold;"&gt;Goal of the day:&lt;/span&gt; investigate on multipath fading problems of previous tests, and on frequency discerning capability of sound sensors.&lt;br /&gt;&lt;br /&gt;In previous session we thought that the unreliability of sound sensor for certain frequencies was due to multipath fading. Since this strange behavior showed only for some frequencies, we thought that using sounds with more than a single frequency we wouldn't get the same effect.&lt;br /&gt;So, we tried a test similar to the previous, but using square waves, because they are made up by more frequencies (all odd harmonics).&lt;br /&gt;We used our pc as sound source again, but this time with a synthesizer software, configured with a square wave sample.&lt;br /&gt;&lt;br /&gt;These are results we obtained with the sound source distant 50cm from the sensor&lt;br /&gt;do3 -&gt; 5&lt;br /&gt;re3 -&gt; 6&lt;br /&gt;mi3 -&gt; 7&lt;br /&gt;fa3 -&gt; 9&lt;br /&gt;sol3 -&gt; 9&lt;br /&gt;la3 -&gt; 12&lt;br /&gt;si3 -&gt; 13c&lt;br /&gt;&lt;br /&gt;do4 -&gt; 11&lt;br /&gt;re4 -&gt; 11&lt;br /&gt;mi4 -&gt; 11&lt;br /&gt;fa4 -&gt; 17&lt;br /&gt;sol4 -&gt; 12&lt;br /&gt;la4 -&gt; 14&lt;br /&gt;si4 -&gt; 20&lt;br /&gt;&lt;br /&gt;do5 -&gt;  15&lt;br /&gt;re5 -&gt; 17&lt;br /&gt;mi5 -&gt; 19&lt;br /&gt;fa5 -&gt; 17&lt;br /&gt;sol5 -&gt; 17&lt;br /&gt;la5 -&gt; 20&lt;br /&gt;si5 -&gt; 21&lt;br /&gt;&lt;br /&gt;do6 -&gt; 21&lt;br /&gt;re6 -&gt; 14&lt;br /&gt;mi6 -&gt; 20&lt;br /&gt;fa6 -&gt; 19&lt;br /&gt;sol6 -&gt; 17&lt;br /&gt;la6 -&gt; 20&lt;br /&gt;si6 -&gt; 17&lt;br /&gt;&lt;br /&gt;and these at distance of 100cm&lt;br /&gt;c4 do -&gt; 4&lt;br /&gt;c4 re -&gt; 7&lt;br /&gt;c4 mi -&gt; 7&lt;br /&gt;c4 fa -&gt; 8&lt;br /&gt;c4 sol -&gt; 9&lt;br /&gt;c4 la -&gt; 11&lt;br /&gt;c4 si -&gt; 11&lt;br /&gt;&lt;br /&gt;c5 do -&gt; 11&lt;br /&gt;c5 re -&gt; 19&lt;br /&gt;c5 mi -&gt; 23&lt;br /&gt;c5 fa -&gt; 15&lt;br /&gt;c5 sol -&gt; 7&lt;br /&gt;c5 la -&gt; 13&lt;br /&gt;c5 si -&gt; 14&lt;br /&gt;&lt;br /&gt;As it can be easily seen, even if these sounds are not made up by a single frequency, they are affected by the same problem, since there is no smooth change between values.&lt;br /&gt;For some reason with square waves we got very low values, even if we used the sound volumes of the previous test.&lt;br /&gt;We obtained constant values for a wide range of notes, and then we got changes that don't seem to follow any regular function.&lt;br /&gt;In addition to this, sometimes sampling continuously same certain notes, we got really fuzzy results.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;Using square waves we got worst results than the previous test.&lt;br /&gt;We think that it is not possible to recognize the frequency range of a sound source, by computing only sound sensor readings in a naive way.&lt;br /&gt;If we still want to do that, we must implement a Fourier transform algorithm, but then we should face some other hardware restrictions, like NXT sensor sampling frequency, or computational capability.&lt;br /&gt;Then we decided to drop the idea of discerning sound sources according to their frequency, even if we could come back to it later. We will use only amplitude of the signal as indication for distance and direction of sound.&lt;br /&gt;Next tests to be done with sounds are only tests with multiple sound sources. We plan to do these tests with a sound follower robot we will build in next sessions, since its results will be easier to understand.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Square_wave"&gt;http://en.wikipedia.org/wiki/Square_wave&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-607083601820029361?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/607083601820029361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=607083601820029361' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/607083601820029361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/607083601820029361'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2008/01/end-course-project-sound-sensor-general.html' title='End Course Project - Sound sensor general tests 2'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-6680471948559773052</id><published>2007-12-07T07:56:00.000-08:00</published><updated>2008-01-24T06:18:07.840-08:00</updated><title type='text'>End Course Project - Sound sensor detailed tests</title><content type='html'>&lt;hr /&gt;Date: 07.12.2007&lt;br /&gt;Duration of activity: 6 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;hr /&gt;&lt;span style="font-weight: bold;"&gt;Goal&lt;/span&gt;: Determine which frequencies will be produced by our sound sources, in order to maximize the sound following capability of our robots.&lt;br /&gt;&lt;br /&gt;In this test session we wanted to do an extensive test of NXT sound sensor response on a wide range of sound frequencies. We hoped to discover some properties of some range of frequencies that can be useful for our project.&lt;br /&gt;We needed at least to find some frequencies which yield sound sensor values proportional to the distance from the sound source, such that the robot can have some indication about the proximity with the sound source, using only sound sensor readings.&lt;br /&gt;&lt;br /&gt;In this test we measured readings of sound sensor values, through pure frequencies sounds from 100 Hz to 10 kHz and were repeated putting the sensor at three different distances from the sound source, at 50, 100 and 200 cm.&lt;br /&gt;As sound source we used speakers of a laptop, and we generated wanted frequencies using a small &lt;a title="NCH Tone-Waveform Generator" href="http://www.world-voices.com/software/nchtone.html"&gt;tone generator&lt;/a&gt; software - (NCH Tone-Waveform Generator).&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158372655934300066"&gt;&lt;img src="http://lh5.google.it/djjeck/R5Y4mbANX6I/AAAAAAAAA48/iBFpGZfJNaM/s144/IMG_3906.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The tests were performed by using a plastic cup on the sensor. As said before, plastic cups will help improving the directionality of the sound sensor, and since we will only use sound sensors with plastic cups, we performed tests under the same condition in which we will use sensors.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#515874743288405970"&gt;&lt;img src="http://lh3.google.it/djjeck/R5Y6f7ANX9I/AAAAAAAAA50/QD0EENHxBs4/s144/IMG_4265.JPG" /&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158372501315477394"&gt;&lt;img src="http://lh5.google.it/djjeck/R5Y4dbANX5I/AAAAAAAAA40/chfu4lUDqqE/s144/IMG_3898.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Values we used are not directly raw values, but they are the mean value of all samples taken during 1 second; we had to use mean values because of the very noisy lego sensor.&lt;br /&gt;In some cases we also repeated tests, when we got "suspicious" readings, so oscillation of values must not be attributed to random sensor noise, it is always an almost reliable mean of values for the specified frequency.&lt;br /&gt;&lt;br /&gt;Those are test results:&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;frequency: Hz&lt;/th&gt;&lt;th&gt;value&lt;br /&gt;at 50cm&lt;/th&gt;&lt;th&gt;value&lt;br /&gt;at 100cm&lt;/th&gt;&lt;th&gt;value&lt;br /&gt;at 200cm&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;200&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;400&lt;/td&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;9&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;450&lt;/td&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;500&lt;/td&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;18&lt;/td&gt;&lt;td&gt;11&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;550&lt;/td&gt;&lt;td&gt;41&lt;/td&gt;&lt;td&gt;23&lt;/td&gt;&lt;td&gt;14&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;600&lt;/td&gt;&lt;td&gt;53&lt;/td&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;38&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;650&lt;/td&gt;&lt;td&gt;52&lt;/td&gt;&lt;td&gt;31&lt;/td&gt;&lt;td&gt;38&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;700&lt;/td&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;13&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;750&lt;/td&gt;&lt;td&gt;85&lt;/td&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;37&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;800&lt;/td&gt;&lt;td&gt;81&lt;/td&gt;&lt;td&gt;43&lt;/td&gt;&lt;td&gt;11&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;850&lt;/td&gt;&lt;td&gt;91&lt;/td&gt;&lt;td&gt;74&lt;/td&gt;&lt;td&gt;22&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;900&lt;/td&gt;&lt;td&gt;90&lt;/td&gt;&lt;td&gt;67&lt;/td&gt;&lt;td&gt;45&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;950&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;td&gt;77&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1000&lt;/td&gt;&lt;td&gt;90&lt;/td&gt;&lt;td&gt;63&lt;/td&gt;&lt;td&gt;29&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1500&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;td&gt;81&lt;/td&gt;&lt;td&gt;37&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2000&lt;/td&gt;&lt;td&gt;81&lt;/td&gt;&lt;td&gt;62&lt;/td&gt;&lt;td&gt;43&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2500&lt;/td&gt;&lt;td&gt;90&lt;/td&gt;&lt;td&gt;76&lt;/td&gt;&lt;td&gt;57&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3000&lt;/td&gt;&lt;td&gt;75&lt;/td&gt;&lt;td&gt;41&lt;/td&gt;&lt;td&gt;39&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3500&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;td&gt;47&lt;/td&gt;&lt;td&gt;6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4000&lt;/td&gt;&lt;td&gt;75&lt;/td&gt;&lt;td&gt;42&lt;/td&gt;&lt;td&gt;10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4500&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;td&gt;60&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5000&lt;/td&gt;&lt;td&gt;72&lt;/td&gt;&lt;td&gt;48&lt;/td&gt;&lt;td&gt;20&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5500&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;td&gt;65&lt;/td&gt;&lt;td&gt;39&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6000&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;td&gt;72&lt;/td&gt;&lt;td&gt;47&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6500&lt;/td&gt;&lt;td&gt;80&lt;/td&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;29&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7000&lt;/td&gt;&lt;td&gt;81&lt;/td&gt;&lt;td&gt;34&lt;/td&gt;&lt;td&gt;10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7062&lt;/td&gt;&lt;td&gt;67&lt;/td&gt;&lt;td&gt;32&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7125&lt;/td&gt;&lt;td&gt;52&lt;/td&gt;&lt;td&gt;22&lt;/td&gt;&lt;td&gt;6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7188&lt;/td&gt;&lt;td&gt;36&lt;/td&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7250&lt;/td&gt;&lt;td&gt;33&lt;/td&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7375&lt;/td&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7500&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7750&lt;/td&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8000&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9000&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10000&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;As it can be seen from this table, we sampled with high density where small variations in frequency gave big changes in readings, while skipping where responses were uniform.&lt;br /&gt;&lt;br /&gt;These are two graphs obtained from the values above:&lt;br /&gt;&lt;br /&gt;2D version&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158391940337459202"&gt;&lt;img src="http://lh3.google.it/djjeck/R5ZKI7ANYAI/AAAAAAAAA6s/ss1qZdiVyzA/s800/grafico2D.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3D version&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5158392013351903250"&gt;&lt;img src="http://lh4.google.it/djjeck/R5ZKNLANYBI/AAAAAAAAA60/5rZRetseR40/s800/grafico3D.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From the graphs above some sounds sensor features come out:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The three shapes in the graph are similar in some way, and there is a decay of readings while the sound source gets far, which is an expected result, and a required condition for our robot to work. This means that near sources will give values higher than distant sources.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It is better if we use frequencies between 1kHz and 7kHz, because sensor responses are more uniform and proportional to sound source distance.&lt;/li&gt;&lt;li&gt;We can notice, by looking at the red line (which corresponds to the test with the closer sound source, 50cm) that the sensor response is not precise, when pushed to high levels, which means that we must consider every sampling above 70 as "loud sound" indistinctly, i.e. using threshold around 70-80 for loud sounds.&lt;/li&gt;&lt;li&gt;It also comes out that there are some frequencies which are still perceived loud by the sound sensor even if they're distant (2.5kHz, 4.5kHz, 6kHz), while others fall down too fast (3.5kHz, 5kHz).&lt;/li&gt;&lt;/ul&gt;Even if this test pointed out some good characteristics of NXT sound sensor, we noticed the non uniform distribution of values, which makes us worry about the possible capability of recognizing different frequencies.&lt;br /&gt;&lt;br /&gt;After some speculation during the tests, we figured out that the problem of that oscillation was given by the environment under which we performed tests: our small office. The sensor readings were probably affected by a phenomenon which in telecommunications field is called multipath fading.&lt;br /&gt;The same sound waves that come out from the sound source arrive more than once to the sensor: first time the waves with a straight path, and immediately afterwards with a different path, after having bounced on the walls. These signals are identical, but with a phase shift, which in some cases can cause them to cancel out partly or completely.&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Image:Multichemin.svg"&gt;&lt;img style="width: 448px; height: 318px;" src="http://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Multichemin.svg/800px-Multichemin.svg.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;We got some good results, like hints about frequencies to use for sound sources.&lt;br /&gt;We will do further investigation on sensing different frequencies, and avoiding multipath fading, to clarify whether the frequency discerning capability is implementable or not.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.mediacollege.com/audio/microphones/directional-characteristics.html"&gt;http://www.mediacollege.com/audio/microphones/directional-characteristics.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Multipath_fading"&gt;http://en.wikipedia.org/wiki/Multipath_fading&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-6680471948559773052?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/6680471948559773052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=6680471948559773052' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/6680471948559773052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/6680471948559773052'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2008/01/end-course-project-sound-sensor.html' title='End Course Project - Sound sensor detailed tests'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-7477803610749247241</id><published>2007-12-07T03:17:00.000-08:00</published><updated>2008-01-24T02:04:51.276-08:00</updated><title type='text'>End Course Project - Bluetooth general tests</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/__NFbv76oeO4/R1kvjWdVIgI/AAAAAAAAAA4/B_ZWU5tJyYg/s1600-h/HaroldBlueTooth.jpg"&gt;&lt;img style="cursor: pointer;" src="http://bp1.blogger.com/__NFbv76oeO4/R1kvjWdVIgI/AAAAAAAAAA4/B_ZWU5tJyYg/s320/HaroldBlueTooth.jpg" alt="" id="BLOGGER_PHOTO_ID_5141192733990658562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;Date: 6.12.2007&lt;br /&gt;Duration of activity: 3 hour&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Goal&lt;/span&gt;: &lt;span class="postbody"&gt;trying to get NXT bricks to communicate each other via Bluetooth&lt;sup&gt;©&lt;/sup&gt;.&lt;br /&gt;&lt;/span&gt;&lt;span class="postbody"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Plan&lt;/span&gt;:&lt;/span&gt;&lt;span class="postbody"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;get used with leJOS Bluetooth API&lt;/li&gt;&lt;li&gt;activate bluetooth on NXT brick and assign a name to each robot&lt;/li&gt;&lt;li&gt;&lt;span class="postbody"&gt;get two NXT bricks to communicate via Bluetooth&lt;/span&gt;&lt;/li&gt;&lt;li&gt;(only if the above test fail) get the NXT brick to communicate with PC&lt;/li&gt;&lt;/ul&gt;&lt;span style="text-decoration: underline;"&gt;leJOS Bluetooth API&lt;/span&gt;&lt;br /&gt;The package that provide all the NXT communication classes is  &lt;span style="font-style: italic;"&gt;lejos.nxt.comm&lt;/span&gt;.&lt;br /&gt;Particularly we are interested in the classes &lt;span style="font-style: italic;"&gt;Bluetooth&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;BTRemoteDevice&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;BTConnection&lt;/span&gt;&lt;span&gt;.&lt;br /&gt;These classes are poorly documented, so we expect for hard work...&lt;br /&gt;&lt;br /&gt;It follows a brief description of each class:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Bluetooth&lt;/span&gt; - it is the main class of this package and it provides all the methods to activate the own bluetooth device, to discover other devices, create connections and communicate with them;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;BTRemoteDevice&lt;/span&gt; - the methods in this class allows to change the parameters of the robot connected with the bluetooth: the  address, the friendly name and the class  which the device belongs to;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;BTConnection&lt;/span&gt; - it represents a connection with another device: using a BTConnection instance you can open streams to write and read data from that device (on the documentation you can read that this classes are "not yet implemented", but we used them with success!).&lt;/li&gt;&lt;/ul&gt; We activate bluetooth on the devices using simply the option Bluetooth --&gt; On/Off on the leJOS interface.&lt;br /&gt;&lt;br /&gt;Then we try to assign a name to both of the robots, using the function &lt;span style="font-style: italic;"&gt;Bluetooth.setFriendlyName&lt;/span&gt;: first of all the function gets as argument a byte array, so w&lt;span class="postbody"&gt;e build an function to  convert the string  into a byte array (all the utility functions and the constant variable are in the file &lt;a href="http://www.daimi.au.dk/~cosenal/legolab/BTUtils.java"&gt;BTUtils.java&lt;/a&gt;).&lt;br /&gt;Applying the &lt;span style="font-style: italic;"&gt;setFriendlyName&lt;/span&gt; using as input the simple string converted into an array we get a strange exception during the execution of the program...ok, no panic...let's go into the source code of the function:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public static void setFriendlyName(byte[] name) {&lt;br /&gt;       byte[] reply = new byte[32];&lt;br /&gt;       byte[] msg = new byte[32];&lt;br /&gt;     &lt;br /&gt;       friendlyName = name;&lt;br /&gt;     &lt;br /&gt;       msg[0] = MSG_SET_FRIENDLY_NAME;&lt;br /&gt;     &lt;br /&gt;       for(int i=-0;i&lt;16;i++) msg[i+1] = name[i];          &lt;br /&gt;       ... &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We just figure out that there is a magic number that the argument must comply with.&lt;br /&gt;After the appropriate modification to the function that convert the string,  we check if the robot changed its name: yes, it works!&lt;br /&gt;To trick to know the name of the robot is to search it from another device: on the screen of this one will appear the name of all the found devices.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="postbody"&gt;&lt;span style="font-weight: bold;"&gt;Subplan&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;send an integer from a robot to another one&lt;/li&gt;&lt;li&gt;send a real time produced stream of data&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span class="postbody"&gt;At this point, after we have stolen some ideas from the leJOS forum, we write the code of two program that are supposed to run in the two robots: the initial idea is just trying to send  an integer value from the transmitter to the receiver. We use the stream abstraction implemented (according to the documentation  they are "not yet implemented"...) on a BTConnection: openDataInputStream() returns a DataInputStream that can be used to receive data and the symmetric openDataOutputStream() returns a DataOutputStream useful to send data.&lt;br /&gt;Thanks to the streams we are allowed to send any type of data: boolean, byte, char, short, int, String; all our test will be based on byte type.&lt;br /&gt;&lt;/span&gt;&lt;span class="artsem"&gt;Obviously&lt;/span&gt;&lt;span class="postbody"&gt; we don't succeed at the first trying, but fortunetly only because of two small errors: we forgot to &lt;span style="font-style: italic;"&gt;flush&lt;/span&gt; the stream after sending  the byte and more stupid to &lt;span style="font-style: italic;"&gt;refresh&lt;/span&gt; the screen on the receiver. After fixed these problems, it works, so we can try the second step of our subplan.&lt;br /&gt;The idea is to generate a stream of data produced by a sensor of a robot, send this stream via bluetooth to the other robot and control a motor of this one using the values received. We are using the MotorPort abstraction, so at the first trying we don't perceive any movement because the scales of values are different: a normalization on the values received makes the system working.&lt;br /&gt;&lt;br /&gt;Files:&lt;br /&gt;&lt;a href="http://www.daimi.au.dk/~cosenal/legolab/BTTransmitterP.java"&gt;BTTransmitterP.java&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.daimi.au.dk/~cosenal/legolab/BTReceiverP.java"&gt;BTReceiverP.java&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;:&lt;br /&gt;We met the first deadline!&lt;br /&gt;We succeeded to get two NXT sending data each other. This will be useful when the robots will have to communicate each other the positions of the sound sources detected. For this purpose other tests will be necessary, i.e. sending a "big" data amount and store it in one of the robot, but the goal of this session was just to prove the feasibility of the idea.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="postbody"&gt;leJOS Forum - http://lejos.sourceforge.net/forum/&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="postbody"&gt;leJOS API  (particularly the section about the communication  package)  - http://lejos.sourceforge.net/p_technologies/nxt/nxj/api/lejos/nxt/comm/package-summary.html&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span class="postbody"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-7477803610749247241?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/7477803610749247241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=7477803610749247241' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/7477803610749247241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/7477803610749247241'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/12/end-course-project-bluetooth-general.html' title='End Course Project - Bluetooth general tests'/><author><name>zimba</name><uri>http://www.blogger.com/profile/05249586150135171428</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/__NFbv76oeO4/R1kvjWdVIgI/AAAAAAAAAA4/B_ZWU5tJyYg/s72-c/HaroldBlueTooth.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-4103017536212309066</id><published>2007-11-30T05:37:00.000-08:00</published><updated>2008-01-24T06:10:10.038-08:00</updated><title type='text'>End Course Project - Sound sensor general tests</title><content type='html'>&lt;hr /&gt;Date: 29.11.2007&lt;br /&gt;Duration of activity: 1 hour&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;&lt;span style="font-weight: bold;"&gt;Goal of the day:&lt;/span&gt; Before definitely choosing our project, we had to make sure that the Lego sound sensors are enough good to be used for the physical implementation of our idea.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Plan:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Find out if the Lego sound sensors can be used to recognize the direction and/or distance of some sound source&lt;/li&gt;&lt;li&gt;If so, define under which conditions it works better&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Plan some tests to be done later in order to clarify some details of our project&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Requirements formalization - An agent of our project:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;must be capable of recognizing the distance of a sound source, using the read value (amplitude).&lt;/li&gt;&lt;li&gt;must be capable of recognizing the direction from which a sound is spread, by using two sound sensors, or by pointing a single sound sensor in different directions.&lt;/li&gt;&lt;li&gt;should be nice if it was capable of distinguishing among two or more different sources, by means of their frequency - in case of a pure frequency sound - or their spectrum - in case of a mixed frequency sound.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;General tests&lt;/span&gt;&lt;br /&gt;We wrote a simple program that just outputs the reading from a single sound sensor. Then we made the first test, to see how the sensor behaves as a directional sensor.&lt;br /&gt;We generated a buzz with our laptop, and moved the sensor around the room to see if values actually changed a bit. We got only slight value changes.&lt;br /&gt;&lt;br /&gt;Then we tried to improve the directionality of the sensor, by building a paper cone around the sensor. We ran the same "approximative" test, and we got very good results: high values when directed to the source, low values otherwise.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We then built a simple tester robot. We mounted the sound sensor upon a motor,&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5141031284113136578"&gt;&lt;img src="http://lh6.google.it/djjeck/R1ictuy728I/AAAAAAAAAzQ/12mczYp7rqA/s144/IMG_3851.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;and we wrote a program that made the sensor rotate by 90 degrees in all four directions, and sample for a while in each direction. Then print out all the mean sound values.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5141031370012482514"&gt;&lt;img src="http://lh6.google.it/djjeck/R1icyuy729I/AAAAAAAAAzU/zybUzGAWBZU/s144/IMG_3854.JPG" /&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5143455697574253042"&gt;&lt;img src="http://lh5.google.it/djjeck/R2E5tKvfUfI/AAAAAAAAAzY/bRWe92yq9DU/s144/IMG_3855.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We tried some different volumes, or with different distance, and we ended up with readings around 60 in the direction of sound, 40 in the opposite direction, and 30 in the other two directions.&lt;br /&gt;&lt;br /&gt;We concluded that the sound sensor behaves as we hoped (actually only for near loud sounds sources as far as we know) and it could therefore be used for our project.&lt;br /&gt;&lt;br /&gt;We noticed that the sensibility range goes from low frequencies, around 200Hz to high frequencies over 1kHz, but the sensor has different sensibilities, depending on the frequency range, for small frequency variations.&lt;br /&gt;&lt;br /&gt;We noticed a trivial thing also, that we didn't think of before: sound waves bounce on the wall, and are heard from the sensor  as if they came from the opposite direction (this is why the sensor outputs greater values when pointing in the direction opposite to the sound source).&lt;br /&gt;We plan that if this problem will affect our agents in their sound locating capability, we could build an environment for them in which sound doesn't bounce on walls, by removing walls (and we would need a very large room) or by making sound absorbed by walls (by covering walls with something).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Further tests plans:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Identify which frequencies can be used by our sound sources, in order to be geographically localizable: we will measure how the sound perception falls, by getting far from the source. We will discard then frequencies that are perceived too weakly from a reasonable distance.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Then we must analyze the sensor behavior with the presence of more than a sound source&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Conclusion:&lt;/span&gt;&lt;br /&gt;As far as we know we could build our agents. We will do further tests in some days.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-4103017536212309066?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/4103017536212309066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=4103017536212309066' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/4103017536212309066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/4103017536212309066'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/12/end-course-project-sound-sensor-general.html' title='End Course Project - Sound sensor general tests'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-3988216907286124867</id><published>2007-11-29T08:28:00.000-08:00</published><updated>2008-01-24T06:14:01.123-08:00</updated><title type='text'>End Course Project - Overview</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Project description:&lt;/span&gt;&lt;br /&gt;Our idea is to build a flock of agents that are attracted by sound sources.&lt;br /&gt;Any agent wants to be within the range of an audio source, together with some other agents.&lt;br /&gt;An audio source is a localized point in the environment, from which sound is spread at a fixed frequency.&lt;br /&gt;The goal of this project is to simulate an artificial population led by specific motivation (our creatures will be constantly hungry for sound waves!) and not merely to create a device that finds sound sources.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Agent description:&lt;/span&gt; an agent is able to&lt;br /&gt;&lt;ul&gt;&lt;li&gt;wander randomly in search of audio sources&lt;/li&gt;&lt;li&gt;build a partial map of the environment&lt;/li&gt;&lt;li&gt;communicate with other agents to help them finding audio sources&lt;/li&gt;&lt;/ul&gt;and possibly&lt;ul&gt;&lt;li&gt;have different preferences on found audio sources&lt;/li&gt;&lt;li&gt;look for other agents, when it is alone&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Required material:&lt;/span&gt;&lt;br /&gt;Each robot should be equipped with two motors, a bump sensor (in order to approximately keep track of directions), and at least two sound sensors.&lt;br /&gt;We cannot be yet sure about the exact number of sound sensors needed, or if we will need to add something to agents.&lt;br /&gt;We will need at least three robots to run the network at the end of the project, but for the main part of our work we will use only one.&lt;br /&gt;&lt;br /&gt;The environment should then contain some small audio sources, which we will try to build from a cheap loudspeaker and a Lego&lt;sup&gt;©&lt;/sup&gt; RCX brick (which are easier to find in the Lego room).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Main challenges:&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Make the Lego sound sensor a directional microphone&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use the microphone to figure out the distance of audio sources&lt;/li&gt;&lt;li&gt;Build an audio source from a Lego RCX brick and a simple loudspeaker&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Collect audio samples to distinguish different frequencies&lt;/li&gt;&lt;li&gt;Use the bluetooth to make agents communicate&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Overall plan (with deadlines):&lt;/span&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Bluetooth general tests&lt;/td&gt;&lt;td&gt;06/12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sound Sensor tests for direction sensibility, distance / amplitude function, frequencies spectrum analysis&lt;/td&gt;&lt;td&gt;08/12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sound locator robot&lt;/td&gt;&lt;td&gt;13/12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Location saving and map building&lt;/td&gt;&lt;td&gt;17/12&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Multi-agent interaction&lt;/td&gt;&lt;td&gt;07/01&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Build environment with sound sources&lt;/td&gt;&lt;td&gt;10/01&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Final tests&lt;/td&gt;&lt;td&gt;15/01&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-3988216907286124867?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/3988216907286124867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=3988216907286124867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/3988216907286124867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/3988216907286124867'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/12/end-course-project-overview.html' title='End Course Project - Overview'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-1980082397622679594</id><published>2007-11-28T12:42:00.000-08:00</published><updated>2007-11-29T05:47:27.005-08:00</updated><title type='text'>NXT Programming - Lesson 10</title><content type='html'>&lt;hr /&gt;Date: 22.11.2007&lt;br /&gt;Duration of activity: 4 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;br /&gt;Goal: Identifying the advantages of a motivation based behaviour in an agent&lt;br /&gt;&lt;br /&gt;Plan:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;rebuild robot&lt;/li&gt;&lt;li&gt;get used with the subsumption API of leJOS NXJ&lt;/li&gt;&lt;li&gt;test the sample program&lt;/li&gt;&lt;li&gt;test with bump sensor pressed&lt;/li&gt;&lt;li&gt;add PlaySound&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;We rebuilt the robot following the classical model described on the Lego&lt;sup&gt;©&lt;/sup&gt; handbook to add the bump sensor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5138254322959999426"&gt;&lt;img src="http://lh5.google.it/djjeck/R06_FUWlYcI/AAAAAAAAAwk/mTIXKDUjgPg/s144/IMG_3849.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Behavior interface was simple to understand, but we spent more time to analyze the code of Arbitrator. After having realized how it is supposed to work, we uploaded the code and tested it.&lt;br /&gt;&lt;br /&gt;On a trivial test, it showed no undesired effect, but when testing, as suggested, with the bump sensor pressed, it stops. This is because, how the Behavior tutorial says, "it executes the action() method of that behavior once and only once".&lt;br /&gt;Since the array of Behaviors is visited from right to the left, and the visit is interrupted whenever a behavior wants to take control, takeControl methods of lower priority Behavior are not called any more.&lt;br /&gt;&lt;br /&gt;Before trying to fix that unwanted behavior, we adapted the PlaySound to implement the Behavior interface, and added it as an high priority behavior, as usual.&lt;br /&gt;That was pretty easy, and worked as usual. It didn't happen that a lower priority behavior is still active when it is suppressed, but we tried to figure out when it could happen:&lt;br /&gt;If the BehaviorAction thread is paused (by the JVM or explicitly) before the Behavior action() method ends, while inside the Arbitrator thread a Behavior with higher priority (PlaySound, in this case) triggers, it can cause some problems.&lt;br /&gt;In this case, the suppress method of the Behavior is called while the action method execution is paused, possibly inside a Thread.sleep() instruction, so it wouldn't stop the action execution from this point to the end. Then the higher level action execution is queued, and will be called when the action method terminates. But in this case, the suppress() method wouldn't be called.&lt;br /&gt;In this case, this issue cannot easily affect the overall Behavior of the robot, since the action method of the HitWall behavior ends with two motor.stop(), but in general it can often cause unexpected behaviors, for instance if the higher priority behavior accesses the motors.&lt;br /&gt;&lt;br /&gt;New plan:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Implement the suggested arbitrator strategy&lt;/li&gt;&lt;li&gt;Analyze possible problems of the implementation&lt;/li&gt;&lt;li&gt;Try the motivation strategy&lt;/li&gt;&lt;/ol&gt;We changed all behaviors, removing the suppression methods and using a Thread strategy: this time Arbitrator interrupts the executing thread to suppress the associate behavior. Because the suppress method is no more used by Arbitrator we put its signature out from the Behavior interface. We created another interface (&lt;a href="http://www.daimi.au.dk/%7Ecosenal/legolab/MotivationBehavior.java"&gt;MotivationBehavior.java&lt;/a&gt;) and adapt all the classes for the motivation behavior architecture: for example, this is the resulting &lt;a href="http://www.daimi.au.dk/%7Ecosenal/legolab/PlaySounds.java"&gt;PlaySounds.java&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;We didn't have time to try a different strategy where the motivation value is based on dynamic factors like the alive time of a behavior.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-1980082397622679594?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/1980082397622679594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=1980082397622679594' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/1980082397622679594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/1980082397622679594'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/11/nxt-programming-lesson-10.html' title='NXT Programming - Lesson 10'/><author><name>zimba</name><uri>http://www.blogger.com/profile/05249586150135171428</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-5828769929020364747</id><published>2007-11-16T04:27:00.000-08:00</published><updated>2007-11-18T06:25:24.160-08:00</updated><title type='text'>NXT Programming - Lesson 9</title><content type='html'>&lt;hr&gt;Date: 15.11.2007&lt;br /&gt;Duration of activity: 4 hours&lt;br /&gt;List of participants: Alessandro, Samuele&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;br /&gt;Goal of the days: Investigate how a Lego NXT robot can keep track of its position and navigate avoiding the obstacles&lt;br /&gt;&lt;br /&gt;First plan:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;measure the physical characteristics of the robot&lt;/li&gt;&lt;li&gt;get used to the Navigator classes&lt;/li&gt;&lt;li&gt;think a way of measuring errors&lt;/li&gt;&lt;li&gt;write the test program&lt;/li&gt;&lt;li&gt;measure Navigator's accuracy&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We used the same robot of the previous lab session: we just made little changes like removing the light sensors. This choice will turn out as a bad choice...&lt;br /&gt;&lt;br /&gt;wheel diameter:&lt;br /&gt;4.32 cm (as written on the tires)&lt;br /&gt;wheel distance:&lt;br /&gt;17.7 cm (measured with a plastic ruler - precision = ± 0.1 cm)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;We copied the Blightbot main program to see if the parameters are correctly passed, and if the overall behaviour seems to be correct: it didn't, we had serious movement issues.&lt;br /&gt;First of all we had to get strongly fixed the position of the motors, which would make the wheel distance be inaccurate.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133424481148494050"&gt;&lt;img src="http://lh6.google.it/djjeck/Rz2WXhgmYOI/AAAAAAAAAso/0Ptr31Hx1Ag/s144/IMG_3668.JPG"&gt;&lt;/a&gt;&lt;br /&gt;Then we avoided that Lego pieces, other than the wheels, touched the ground and modified the precision of the robot movements.&lt;br /&gt;&lt;br /&gt;We tested the robot again to follow the same path as the original Blightbot:&lt;br /&gt;0,0&lt;br /&gt;100,0&lt;br /&gt;50,50&lt;br /&gt;50,-25&lt;br /&gt;0,0&lt;br /&gt;&lt;br /&gt;We had friction problems with the tape on the ground. When the robot drives over it, sometimes a motor loses contact with the floor, and the robot rotates of many degrees.&lt;br /&gt;&lt;br /&gt;Positions after three consecutive runs of the algorithm&lt;br /&gt;start:&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133446617409937746"&gt;&lt;img src="http://lh4.google.it/djjeck/Rz2qgBgmYVI/AAAAAAAAAuU/TLm9HWjcq-8/s144/IMG_3675.JPG"&gt;&lt;/a&gt;&lt;br /&gt;end:&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133446729079087458"&gt;&lt;img src="http://lh6.google.it/djjeck/Rz2qmhgmYWI/AAAAAAAAAuc/SFT5C74G1nU/s144/IMG_3676.JPG"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We also tried to remove all unnecessary stuff, to make it more stable.&lt;br /&gt;We passed to the next step anyway, to quantify the error more precisely.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Rotation accuracy quantification&lt;br /&gt;In order to amplify the angle error, after a rotation, we made the robot go far (10 meters), rotate 180 degrees and then come back.&lt;br /&gt;Then, the distance from the start and end point is proportional to the error angle&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Nice try, but the error is in the order of ten degrees, so this test is not appropriate, we had to try a completely different approach.&lt;br /&gt;&lt;br /&gt;New tests:&lt;br /&gt;Naive test with a single 360° rotation&lt;br /&gt;start&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133424820450910482"&gt;&lt;img src="http://lh5.google.it/djjeck/Rz2WrRgmYRI/AAAAAAAAAtA/Ie8VpD77BSc/s144/IMG_3692.JPG"&gt;&lt;/a&gt;&lt;br /&gt;end&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133424923530125602"&gt;&lt;img src="http://lh5.google.it/djjeck/Rz2WxRgmYSI/AAAAAAAAAtI/TALiEOHFDQg/s144/IMG_3695.JPG"&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133425043789209906"&gt;&lt;img src="http://lh5.google.it/djjeck/Rz2W4RgmYTI/AAAAAAAAAtQ/uT1-rX_TCCk/s144/IMG_3696.JPG"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;New rotation quantification algorithm&lt;br /&gt;Simply rotate in place of 360°, and estimate the error angle.&lt;br /&gt;A way to measure such a big angle is to make the robot continuously rotate of pi, and count at which iteration of this rotation it becomes aligned again, i.e. among how many iterations it loses 180°.&lt;br /&gt;We added a light sensor, calibrated on a small white paper stripe, and added a control that makes the robot stop rotating of 180° when it sees again the stripe.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133425567775220034"&gt;&lt;img src="http://lh3.google.it/djjeck/Rz2XWxgmYUI/AAAAAAAAAtw/SE0Yy159txc/s144/IMG_3703.JPG"&gt;&lt;/a&gt;&lt;br /&gt;We found then an interesting result: at first rotations, the robot lost many degrees per rotation. Then, it precision became higher, probably because the dust that made the robot lose friction was gone after some rotations.&lt;br /&gt;After 87 rotations the robot became aligned again, i.e. it made 86 180° real rotations in 87 "software" rotations.&lt;br /&gt;Effective rotation: x = 180*86/87 = 177.93°&lt;br /&gt;Mean rotation error: e = 180-177.93 = 2.07°&lt;br /&gt;&lt;br /&gt;We couldn't think of a test for distance, without a ruler, since if the robot loses an amount of distance proportional to the travelled distance, every geometric shape you can think is uniformly scaled. And if it doesn't, it's even worse without a ruler.&lt;br /&gt;&lt;br /&gt;We decided to go on with the lab session, and see if this loss of precision sensibly affects the overall behaviour of a navigator robot.&lt;br /&gt;&lt;br /&gt;Goal:&lt;br /&gt;Write an algorithm that can make drive the robot from one point to another, and avoid obstacles if any.&lt;br /&gt;&lt;br /&gt;We wanted to use the lejos Navigator classes, and in order to do so, every robot movement must be made through that interface, otherwise it would have lost track of its position at each encountered obstacle.&lt;br /&gt;We decided the following strategy: make the robot go toward the goal position, if there is no near obstacle, and whenever one is found, make it go left or right to avoid it, and then make it go again toward the goal position.&lt;br /&gt;&lt;br /&gt;pseudocode:&lt;br /&gt;&lt;pre&gt;while not on goal {&lt;br /&gt; sample distance ahead&lt;br /&gt; if (obstacle) {&lt;br /&gt;  avoid&lt;br /&gt; }&lt;br /&gt; else {&lt;br /&gt;  go to goal&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Translating into java code we couldn't use the goTo method, since it doesn't support the returnImmediately flag, so we used this little trick instead:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;navigator.rotateTo(navigator.angleTo(x,y));&lt;br /&gt;navigator.travel(navigator.distanceTo(x,y), true);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then, we had to force the navigator class to update its position, because whenever we called the stop method while the robot was moving, its position was lost.&lt;br /&gt;&lt;br /&gt;Avoid strategy:&lt;br /&gt;&lt;pre&gt;rotate 90°&lt;br /&gt;if(obstacle)&lt;br /&gt;rotate 180°&lt;br /&gt;if(obstacle)&lt;br /&gt; beep //stuck in an angle&lt;br /&gt; return&lt;br /&gt;drive 20cm&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The algorithm worked well, avoiding a single small or big obstacle to get to the goal point.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133456143647400306"&gt;&lt;img src="http://lh6.google.it/djjeck/Rz2zKhgmYXI/AAAAAAAAAvc/Ua13XU1VgY8/s144/IMG_3710.JPG" /&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133456251021582722"&gt;&lt;img src="http://lh3.google.it/djjeck/Rz2zQxgmYYI/AAAAAAAAAvk/-CN_f-1qDwk/s144/IMG_3711.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;However, the navigator precision is affected by how many rotation it does, i.e. the number of obstacles it encounters on the way.&lt;br /&gt;The algorithm could probably have worked even with a goal in a different room, making the robot find the door (if the door is on the right, actually), but after some rotations, the robot completely loses track of its position, and the robot randomly wanders.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-5828769929020364747?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/5828769929020364747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=5828769929020364747' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/5828769929020364747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/5828769929020364747'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/11/nxt-programming-lesson-9.html' title='NXT Programming - Lesson 9'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-7855222767598091627</id><published>2007-11-09T10:01:00.000-08:00</published><updated>2007-11-16T05:04:17.912-08:00</updated><title type='text'>NXT Programming - Lesson 7+8</title><content type='html'>&lt;hr /&gt;Date: 1.11.2007 - 8.11.2007&lt;br /&gt;Duration of activity: 3+4 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;Note: we are writing a single lab report for two lab sessions because we couldn't complete the first lab assignment on time, so we continued the following session.&lt;br /&gt;&lt;br /&gt;Goal of the days: &lt;em&gt;"Many of the proposed experiments could be done with the Lego Mindstorms kit"&lt;/em&gt; - Valentino Braitenberg&lt;br /&gt;&lt;br /&gt;First plan:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Build again the same robot car (which we always destroy for some reason at the end of each lab session)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Write the code for the Braitenberg Vehicle 2a&lt;/li&gt;&lt;li&gt;Test it&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Invert left and right light sensors cables, so we have Vehicle 2b&lt;/li&gt;&lt;li&gt;Test it&lt;/li&gt;&lt;/ol&gt;The first two phases were completed at the same time. Alessandro had some ideas about the hardware structure that we didn't dare to disagree with, so we ended up with this robot &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5132475905123772370"&gt;&lt;img src="http://lh6.google.it/djjeck/Rzo3pIcnZ9I/AAAAAAAAAmI/RZYJwvPLgiE/s144/IMG_3598.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;We used old light sensors, since we only have one NXT light sensor.&lt;br /&gt;We didn't write a normalization with a max and min light, but only converted the light signal into the same range of the motor proportionally.&lt;br /&gt;&lt;br /&gt;Phase 3, test:&lt;br /&gt;The motors moved, but the robot didn't react to any light change. Then we remembered that old light sensor have a very tight actual range of values.&lt;br /&gt;With a small program we then got the raw readings from the sensors.&lt;br /&gt;minimum (ambient) light: 50%&lt;br /&gt;maximum (with a lamp in front of it) light: 60%&lt;br /&gt;But then, we discovered an unexpected result from an error. We forgot to passivate sensors, and obtained a much wider range:&lt;br /&gt;minimum: 25%&lt;br /&gt;maximum: 65%&lt;br /&gt;We thought that the red led should have been used only for distinguishing colors even with low ambient light, but then we discovered that even if the red light doesn't reach any near object, it amplifies the range of ambient light.&lt;br /&gt;&lt;br /&gt;New plan:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;using light sensors in active mode&lt;br /&gt;&lt;/li&gt;&lt;li&gt;now that we understood why it is useful, write a normalization function, with a fixed max and min value&lt;/li&gt;&lt;li&gt;test if the robot moves this time&lt;br /&gt;&lt;/li&gt;&lt;li&gt;implementing the dynamic max and min threshold update (we have to decide how long lasting should thresholds be)&lt;/li&gt;&lt;li&gt;test again&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Normalization:&lt;br /&gt;first of all we transform the value read from the light sensor in the motor scale.&lt;br /&gt;&lt;pre&gt;lightValue * MAX_SPEED / MAX_LIGHT&lt;/pre&gt;&lt;br /&gt;but, since we got only values starting from around 40, before applying the proportion, we apply also a translation to the light values, with the new 0 at MIN_LIGHT&lt;br /&gt;&lt;pre&gt;(lightValue - MIN_LIGHT) * MAX_SPEED / (MAX_LIGHT - MIN_LIGHT)&lt;/pre&gt;&lt;br /&gt;Then, as we want our robot to move even when it only sees darkness, we add a fixed MIN_SPEED value to the resulting speed, and in order to do so, we reduce the space in which we project light readings&lt;br /&gt;&lt;pre&gt;MIN_SPEED + (lightValue - MIN_LIGHT) * (MAX_SPEED - MIN_SPEED) / (MAX_LIGHT - MIN_LIGHT)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now the robot behaves in a nice way. While testing the Braitenberg Vehicle 2b, it drives toward light, though it has a small range of sight, and often it misses the light.&lt;br /&gt;&lt;br /&gt;Then we got to the dynamic threshold algorithm.&lt;br /&gt;We had to force an explicit sleep (20 ms) in sampling threads (which we didn't include at first), otherwise we would have got too many samples.&lt;br /&gt;We implemented a circular queue, which holds every sampled value, up to N, and then starts to discarding old values. We set the size of the queue as &lt;pre&gt;N = MEMORY_TIMEOUT / THREAD_SLEEP,&lt;/pre&gt;where &lt;span style="font-style: italic;"&gt;MEMORY_TIMEOUT&lt;/span&gt; (5000 ms in our tests) is the maximum life of a threshold value.&lt;br /&gt;&lt;br /&gt;In a previous implementation we recalculated thresholds, iterating through the whole queue, at each sensor sampling. Then we thought that it's more efficient to recalculate max and min thresholds only when either the current max or min value is removed from the queue.&lt;br /&gt;&lt;br /&gt;Our implementation worked, without a sensible slowing, but in practice its memory was actually longer than we thought. Since it is a good approximation anyway, and the delay is probably related to the way the lejos JVM manages thread, we chose to not investigate further, and leave it as it is.&lt;br /&gt;&lt;br /&gt;Last plan for lecture 7&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Move to a Multi-threading implementation&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;We isolated the code for the connection between a single light sensor and a single motor. This code has been then put inside a subclass of Thread.&lt;br /&gt;The main program looked like&lt;br /&gt;&lt;pre&gt;new BraitenbergConnection(sensorLeft, motorRight).start();&lt;br /&gt;new BraitenbergConnection(sensorRight, motorLeft).start();&lt;br /&gt;&lt;/pre&gt;This update made the code more readable and modular, but it didn't affect the overall behaviour of the robot, even if presumably the JVM does not implement a perfect parallelization of the process.&lt;br /&gt;&lt;br /&gt;Lesson 8 plan:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Read the assignment, which has a few questions&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Test and analyze the BehaviourTest program&lt;/li&gt;&lt;li&gt;Refactor the previous lab session code, according to Rodney Brooks' subsumption architecture&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;em&gt;&gt;&gt;What is the purpose of making these threads daemon threads?&lt;/em&gt;&lt;br /&gt;We read the lejos doc and made a quick test: if we don't, when the main method terminates other threads keep running. And by default, threads are not daemons.&lt;br /&gt;&lt;em&gt;&lt;br /&gt;&gt;&gt;How is this boolean used in Locomotion.java? And how would you describe the delay method in Behaviour.java used by the behaviour threads?&lt;/em&gt;&lt;br /&gt;In the subsumption architecture paradigm, inputs are inhibited and outputs are suppressed.&lt;br /&gt;The boolean variable is used inside the delay function to suppress the input (i.e. replacing the "wakeup signal" of the returning of the delay method), and inside Locomotion functions to inhibit the output. (Yeah, in this case it is pretty much the same thing).&lt;br /&gt;&lt;em&gt;&lt;br /&gt;&gt;&gt;How is the suppression mechanism used in Behaviour.java to obtain controlled access to the motors? Could you think of situations where this method fails?&lt;/em&gt;&lt;br /&gt;Every access to the motors is contained between the suppression and the unsuppression of any module that the current module can suppress. Then, if some other [more important] Behaviour needs to access the motors, that Behaviour must suppress modules which are currently using the motors.&lt;br /&gt;If the modules are hierarchically ordered, it should never happen that it fails. If they are ordered in a graph-like shape, then concurrent Behaviours could be acting. In that case it should be assured that it can never happen that two concurrent modules require the same resource at the same time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Having already adapted the Braitenberg connection between a sensor and a motor inside a single thread, we just added the Behaviour class as parent class, and adapted the code a bit, and we got a "Drive toward light" Behaviour, actually made up by two concurrent Behaviours (accessing half of the resources each).&lt;br /&gt;We then rewrote the main method, according to this architecture:&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5132478662492776450"&gt;&lt;img src="http://lh4.google.it/djjeck/Rzo6JocnaAI/AAAAAAAAAm4/U7VXOB4S0Tw/s144/brooks.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It worked. Our robot now wanders around, and follows the light when it sees it. It avoids obstacles, even small ones, and plays an annoying sound every 10 seconds.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5133421088124330194"&gt;&lt;img src="http://lh4.google.it/djjeck/Rz2TSBgmYNI/AAAAAAAAAsE/HgjqiacRmcg/s144/IMG_3628.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;The only thing that could be fixed is that the PlaySound has no sense to be there. It should not have that high priority, which avoids sometimes the robot to correctly drive away from obstacles, other than being annoying. But we would have too few modules to make a graph with, so it's fine as it is.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5132478379024934898"&gt;&lt;img src="http://lh6.google.it/djjeck/Rzo55IcnZ_I/AAAAAAAAAmw/5Qy6pH98a-k/s144/funziona.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;Since the robot worked really fine, and showed a really precise light following behaviour, then we started to play with it and forgot about further experiments, so this post ends here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-7855222767598091627?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/7855222767598091627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=7855222767598091627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/7855222767598091627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/7855222767598091627'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/11/nxt-programming-lesson-78.html' title='NXT Programming - Lesson 7+8'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-2296905986844252427</id><published>2007-10-16T01:42:00.000-07:00</published><updated>2007-10-16T02:19:12.192-07:00</updated><title type='text'>NXT Programming - Lesson 6</title><content type='html'>&lt;hr /&gt;Date: 10.10.2007&lt;br /&gt;Duration of activity: 3 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;Goal of the day: Build a balancing robot.&lt;br /&gt;&lt;br /&gt;First of all we followed the Philippe Hurbain building instructions to build the balancing robot. Then we tried a naive proportional implementation, for its software, and then compared to the Philippe Hurbain code.&lt;br /&gt;The result wasn't satisfying. Since its many falls, we added some &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5121851466756789170"&gt;&lt;img src="http://lh4.google.it/djjeck/RxR4xbRaE7I/AAAAAAAAAkg/go751dRkKGs/s144/IMG_2526.JPG" /&gt;&lt;/a&gt; to the robot, to avoid damage to it.&lt;br /&gt;&lt;br /&gt;Then, instead of changing the constants inside of the code to make it work better, we tried some hardware modifications.&lt;br /&gt;&lt;br /&gt;First, we tried to move the robot's weight to the bottom, to make it more firm, as the gyroscope does.&lt;br /&gt;It actually was better in recovering, when it was about to fall, but it oscillated more.&lt;br /&gt;&lt;br /&gt;Then "somebody" made us notice that it would have been easier to balance, moving the weight to the top of the robot. We then built our ridiculous robot of the week: &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5121851651440382914"&gt;&lt;img src="http://lh3.google.it/djjeck/RxR48LRaE8I/AAAAAAAAAko/b_fxkd5wKe0/s144/IMG_2530.JPG" /&gt;&lt;/a&gt;.&lt;br /&gt;It worked better with balancing, but it only could stand small oscillations. Whenever there was an error, it couldn't recover from it, since a bigger motor power should have been required (or a more precise sensor, to avoid such oscillations).&lt;br /&gt;&lt;br /&gt;In order to build a good balancing robot, we then think that it is necessary that its mass center is located at an height proportional to motors power, depending also on the maximum angle (and speed of fall) of recovering tolerance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-2296905986844252427?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/2296905986844252427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=2296905986844252427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/2296905986844252427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/2296905986844252427'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/10/nxt-programming-lesson-6.html' title='NXT Programming - Lesson 6'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-5863151634125346061</id><published>2007-10-06T07:53:00.000-07:00</published><updated>2007-10-06T09:00:24.222-07:00</updated><title type='text'>NXT Programming - Lesson 5 - The Race</title><content type='html'>&lt;hr /&gt;Date: 03.10.2007&lt;br /&gt;Duration of activity: 2 in the morning + 3 hours of lab session&lt;br /&gt;List of participants: Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;Goal of the day: come up with some idea, and decide how to compete&lt;br /&gt;&lt;br /&gt;First of all we tried the same algorithms used the previous session, but with sensors aligned to the wheel axis.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/20071004LegolabRace/photo#5118221124164534626"&gt;&lt;img src="http://lh4.google.it/djjeck/RweS_rO6QWI/AAAAAAAAAdo/7HROgNMN6mc/s144/IMG_2387.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;Results where almost the same&lt;br /&gt;&lt;br /&gt;Then we started dealing with the second idea.&lt;br /&gt;As a generalization of the Y shaped robot thought the previous day, we thought to design the robot with a symmetric shape.&lt;br /&gt;It would have then no need to never rotate, but it could choose to move straight in one of six directions, putting the three motors in the same shape as the sensors, and activating one or two of them, and making the others push in the opposite direction.&lt;br /&gt;In this model, every motor always pushes in the direction of the movement, and two other motors push in a direction which forms an angle of Pi/6 with the movement direction.&lt;br /&gt;Their summed power, regardless of friction, is then always, where p is the power of a single motor:&lt;br /&gt;p + 2 * cos(Pi/6) * p = p + 2 * [sqrt(3) / 2] * p = [1+sqrt(3)] * p, which is more than 2 * p&lt;br /&gt;&lt;br /&gt;Encouraged from the theoretical demonstration that our robot would have always run faster than any other robot with only two motors, we started building it.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/20071004LegolabRace/photo#5118226806406267250"&gt;&lt;img src="http://lh3.google.it/djjeck/RweYKbO6QXI/AAAAAAAAAdw/esRWp_8ging/s144/IMG_2388.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/20071004LegolabRace/photo#5118227085579141506"&gt;&lt;img src="http://lh4.google.it/djjeck/RweYarO6QYI/AAAAAAAAAd4/ykO9m4L0GOs/s144/IMG_2389.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/20071004LegolabRace/photo#5118227738414170514"&gt;&lt;img src="http://lh4.google.it/djjeck/RweZArO6QZI/AAAAAAAAAeA/O3iknmecMms/s144/IMG_2390.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/20071004LegolabRace/photo#5118227940277633442"&gt;&lt;img src="http://lh3.google.it/djjeck/RweZMbO6QaI/AAAAAAAAAeM/ciGRA034J6M/s144/IMG_2392.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;And here it is. Its name is Omega3.&lt;br /&gt;&lt;br /&gt;Then, we started all over with programming it.&lt;br /&gt;We created a TriangularLocomotion class, which supports 6 directions, and a TriangularSight class, which represents the abstraction of the three outer sensors, telling in which of the 6 directions it sees the line.&lt;br /&gt;&lt;br /&gt;The hardware test, with a simple algorithm that moved the locomotion where the sight saw the line, made it go back and forth over the line, since the concept of following wasn't injected in it yet, and it simply "stayed" on the line. It seemed promising, we went on programming.&lt;br /&gt;&lt;br /&gt;We started with a simple stateless algorithm, that decided the direction to follow only using the sensor "sight", and the expected direction of the path (to make it know that it has to follow that direction, and can therefore apply only slight direction changes, and not going back).&lt;br /&gt;We had troubles to make it move, and decided that such a structure, without any built-in concept of what is forward and what is backward, needed an algorithm with a state.&lt;br /&gt;&lt;br /&gt;We wrote then a direction buffer class, with the methods insertLinePosition and getDirection.&lt;br /&gt;It receives every sampling, makes some assumptions, and then figures out the new direction.&lt;br /&gt;Internal states of this class were then coded to Forward, WaitingForBend and Bending.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;When in the forward state, the robot always goes straight if it sees a line in that direction (regarding of other sensors).&lt;br /&gt;When it loses the line, it moves to WaitingForBend state, because when the ahead sensor goes off the line, you expect that the sensors, which are probably out of the line, will cross it as well.&lt;/li&gt;&lt;li&gt;When in the WaitingForBend state, then, you just take the direction of the first sensor which crosses the line, and go in Bending state.&lt;/li&gt;&lt;li&gt;In Bending state, then, you are allowed to apply some correction to the trajectory, by considering the whole sensors reading, and going in the direction in which you see the line, if this implies only a small correction to the direction, or ignoring the sensor reading if it suggests to go backward.&lt;/li&gt;&lt;/ul&gt;Everything was coded, debugged and tested for hours, but we couldn't make it work. It moved, but it didn't follow any line for more than some seconds.&lt;br /&gt;We are sure that in a perfect world, with continuous sensor readings, or at least more frequent and precise, our robot would have worked really nice. But it wasn't the case.&lt;br /&gt;&lt;br /&gt;Goals reached: learned that you should try to use strange strategies to do much better than the others, only when you have backed up your old robot with your old algorithms, which could at least run as the others do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-5863151634125346061?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/5863151634125346061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=5863151634125346061' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/5863151634125346061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/5863151634125346061'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/10/nxt-programming-lesson-5-race.html' title='NXT Programming - Lesson 5 - The Race'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-3721680853106445504</id><published>2007-10-06T06:26:00.000-07:00</published><updated>2008-05-31T13:24:12.872-07:00</updated><title type='text'>NXT Programming - Pre race</title><content type='html'>&lt;hr /&gt;Date: 03.10.2007&lt;br /&gt;Duration of activity: 4 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;Goal of the day: Speed up our robot.&lt;br /&gt;&lt;br /&gt;We fixed up some minor issues, and we made some tests on the work from the previous session: the line following we ended up with was satisfying, but it was too slow.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5118215368908357794"&gt;&lt;img src="http://lh4.ggpht.com/djjeck/RweNwrO6QKI/AAAAAAAAAcM/mEweu0_TndU/s144/IMG_2367.JPG" /&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5118214724663263378"&gt;&lt;img src="http://lh6.ggpht.com/djjeck/RweNLLO6QJI/AAAAAAAAAcE/NSbc41x0gJU/s144/IMG_2366.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Every algorithm we designed for our robot, since we started this course, stopped to behave how it should, when pushed to higher speed. We tried to figure out why, but some behaviors still remain a mystery.&lt;br /&gt;Since the goal of this session was to speed up the robot, we decided to design and test our algorithm without starting with low speeds, but directly pushed to the maximum speed.&lt;br /&gt;&lt;br /&gt;We made some decisions, like to turn without slowing down, after having lost the line, and hope to get back on it later. We increased motor speeds, and only decided the radius of the rotations when turning, and not the robot speed, which should be always to the max.&lt;br /&gt;To bad that every change that we made just made the robot less precise, as you can see from this sadly funny video: &lt;object height="350" width="425"&gt; &lt;param name="movie" value="http://www.youtube.com/v/wxbbRCcDTac"&gt;  &lt;embed src="http://www.youtube.com/v/wxbbRCcDTac" type="application/x-shockwave-flash" height="350" width="425"&gt;&lt;/embed&gt;  &lt;/object&gt;&lt;br /&gt;&lt;br /&gt;As it wasn't enough, while pushing the robot to its limits, it left us, smashing itself on a wall.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5118216309506195682"&gt;&lt;img src="http://lh3.ggpht.com/djjeck/RweOnbO6QOI/AAAAAAAAAcs/eqrJGWv9p8w/s144/IMG_2377.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;We then decided to change our approach to the problem.&lt;br /&gt;We thought, and still are convinced, that the main problem is making the robot turn around some arbitrary axis, making it describe an arc, and assuming it rotates instantly around the center of sensors axis.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5118215884304433362"&gt;&lt;img src="http://lh4.ggpht.com/djjeck/RweOOrO6QNI/AAAAAAAAAck/WvWaExQpwAw/s144/IMG_2373.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A proposal came up: never making the robot turn while moving, but only rotating at regular intervals, in order to avoid the arc problem.&lt;br /&gt;A such algorithm should then make the robot go straight, sample for a certain amount of time, and try to figure out the angle of which to turn, after the sampling phase.&lt;br /&gt;In that graph we represented (while not playing, on the lower part of the board) the sensor readings in function of time, and tried to imagine how can a sampling phase be interpreted, and how you can rotate the robot of a certain angle.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/20071003LegolabPreRace/photo#5118215648081232050"&gt;&lt;img src="http://lh5.google.it/djjeck/RweOA7O6QLI/AAAAAAAAAcU/LJOXZo91_K8/s144/IMG_2368.JPG" /&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.it/djjeck/20071003LegolabPreRace/photo#5118218414040170802"&gt;&lt;img src="http://lh5.google.it/djjeck/RweQh7O6QTI/AAAAAAAAAdU/efrkZo5mhK4/s144/IMG_2379.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After those graphs, an implementation followed. Useless to say it didn't work. Too complicated, sensors too inaccurate, too much particular cases (you're already on the line, you approach the line but don't go after it, you don't see the line at all, you see two lines...).&lt;br /&gt;&lt;br /&gt;We were about to try moving the sensors, to put them on the same axis of the wheels, to make them rotate together, but it was too late.&lt;br /&gt;&lt;br /&gt;And another idea was around already: to put sensors in a Y shape &lt;a href="http://picasaweb.google.it/djjeck/20071003LegolabPreRace/photo#5118215802700054722"&gt;&lt;img src="http://lh5.google.it/djjeck/RweOJ7O6QMI/AAAAAAAAAcc/ccxCzXzv7bM/s144/IMG_2369.JPG" /&gt;&lt;/a&gt;, to make them see forward, when a turn approaches, and using the two sensors behind the robot to be sure you are aligned to the line.&lt;br /&gt;&lt;br /&gt;Anyway, everything was delayed to the next day.&lt;br /&gt;Goals reached: none.&lt;br /&gt;Ideas left to try: some&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-3721680853106445504?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/3721680853106445504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=3721680853106445504' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/3721680853106445504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/3721680853106445504'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/10/nxt-programming-pre-race.html' title='NXT Programming - Pre race'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/djjeck/RweNwrO6QKI/AAAAAAAAAcM/mEweu0_TndU/s72-c/IMG_2367.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-6303102359415061068</id><published>2007-09-27T13:40:00.000-07:00</published><updated>2007-10-06T09:11:12.050-07:00</updated><title type='text'>NXT Programming - Lesson 4</title><content type='html'>&lt;hr /&gt;Date: 27.07.2007&lt;br /&gt;Duration of activity: 4 hours&lt;br /&gt;List of participants: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;Goal of this session: Build the fastest line follower and win the competition of the next week.&lt;br /&gt;&lt;br /&gt;First of all we just wrote a simple program that uses the BlackWhiteSensor class, which just calibrates its threshold, and prints out values. Black is black, white is white, red, orange, green are white as well.&lt;br /&gt;Since we have in mind of building our competition robot using more than one sensor, and we only have one NXT light sensor, we took some other old sensors from the lego room.&lt;br /&gt;Then we modified our test program, and the BlackWhiteSensor class to check if both sensors behave the same (it could be a dangerous to do this assumption without verifying).&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114989792349976882"&gt;&lt;img src="http://lh6.google.it/djjeck/RvwYHaLE-TI/AAAAAAAAAHo/z9tu47KI7Ao/s144/IMG_2151.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;Values sampled by RCX and NXT light sensors are really different, so we decided to not use different types of sensors at the same time. NXT sensor seems more sensible, but we can get more of the old ones, so we had to find only an adapter for RCX sensors.&lt;br /&gt;Let's try the old sensors.&lt;br /&gt;We added the four sensors in a row, in place of the NXT one, and made few modifications to the robot structure (i.e. bigger wheels, to increase the speed)&lt;span style="text-decoration: underline;"&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114989925493963138"&gt;&lt;img src="http://lh5.google.it/djjeck/RvwYPKLE-YI/AAAAAAAAAIQ/FlQEZn9GsBA/s144/IMG_2156.JPG" /&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114989989918472610"&gt;&lt;img src="http://lh4.google.it/djjeck/RvwYS6LE-aI/AAAAAAAAAIk/z3sxTEabZd8/s144/IMG_2158.JPG" /&gt;&lt;/a&gt;&lt;/span&gt;.&lt;br /&gt;We also edited the BlackWhiteSensor class to a RCXBlackWhiteSensor, and then extended it as RCXColorSensor. It has a calibration phase which samples black, green and white, and then calculates two thresholds to distinguish the three colors.&lt;br /&gt;Unfortunately it wasn't going to work: old RCX sensors sample the same value (around 34 with that ambient light) for white, green, red, and probably other colors we didn't try.&lt;br /&gt;We must make the robot distinguish a green area, so we ended up with two possible solutions:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Using the NXT sensor as main sensor, and two RCX sensors for auxiliary sensors. In this case the line following algorithm actually follows the border between black and white, and not the real thick line.&lt;/li&gt;&lt;li&gt;Using two old RCX sensors as main sensors, and other two as auxiliary. In this case the line following algorithm would mainly have to keep the two main sensors inside the black line, and the two auxiliary sensors out of the line. To recognize the green area we can just assume that when we cannot see any black line at all, we are inside the green area.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Since we already had wondered too much about the four-sensor solution &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114990067227883986"&gt;&lt;img src="http://lh6.google.it/djjeck/RvwYXaLE-dI/AAAAAAAAAI8/8knX2Dosskg/s144/IMG_2161.JPG" /&gt;&lt;/a&gt;, and we believe that the first algorithm would be too slow for a speed competition, we chose the second solution.&lt;br /&gt;&lt;br /&gt;The first naive attempt at low speed seemed to work well, so we managed to increase the speed, while keeping its line following accurate. We designed an algorithm to make the robot behave according to the four sensor readings, in a stateless way.&lt;br /&gt;The following are the valid sensor states that we considered:&lt;br /&gt;(one bit per sensor reading, 0 stands for sensing white, 1 for black)&lt;br /&gt;&lt;br /&gt;forward&lt;br /&gt;0110 on the line, fast forward&lt;br /&gt;1111 maybe crossing another line, forward&lt;br /&gt;&lt;br /&gt;right&lt;br /&gt;0001 strange turn, probably recovering from a previous turn, gentle turn right&lt;br /&gt;0011 normal turn, right&lt;br /&gt;0111 possible 90° turn, fast turn right&lt;br /&gt;&lt;br /&gt;left, same as above&lt;br /&gt;1000 gentle turn left&lt;br /&gt;1100 left&lt;br /&gt;1110 fast turn left -&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114990101587622386"&gt;&lt;img src="http://lh6.google.it/djjeck/RvwYZaLE-fI/AAAAAAAAAJM/Lx_vy0nqzNk/s144/IMG_2163.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;stop&lt;br /&gt;0000 no black line, stop&lt;br /&gt;&lt;br /&gt;Every other state has been discarded as a glitch in sampling or an unknown state. In those cases the robot simply ignores the reading and keeps driving with no speed changes.&lt;br /&gt;&lt;br /&gt;Since it wasn't that easy to make it work with higher speeds, a long discussion followed, about interpretation of robot readings &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114990178897033794"&gt;&lt;img src="http://lh4.google.it/djjeck/RvwYd6LE-kI/AAAAAAAAAJ0/dqEgANLb4WM/s144/IMG_2168.JPG" /&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114990161717164594"&gt;&lt;img src="http://lh4.google.it/djjeck/RvwYc6LE-jI/AAAAAAAAAJs/CVX0I96ete0/s144/IMG_2167.JPG" /&gt;&lt;/a&gt;, or alternative positioning of the sensors &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114990144537295394"&gt;&lt;img src="http://lh4.google.it/djjeck/RvwYb6LE-iI/AAAAAAAAAJk/_1a8nBN9ArM/s144/IMG_2166.JPG" /&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;At last, we ran out of ideas, so we decided to stop working, and continuing later &lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5114990208961804882"&gt;&lt;img src="http://lh3.google.it/djjeck/RvwYfqLE-lI/AAAAAAAAAJ8/mcG3d2kb-CQ/s144/IMG_2173.JPG" /&gt;&lt;/a&gt;. It wasn't that bad, but we need some intuition, which is not easy to have, after four hours of work. Updates will follow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-6303102359415061068?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/6303102359415061068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=6303102359415061068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/6303102359415061068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/6303102359415061068'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/09/nxt-programming-lesson-4.html' title='NXT Programming - Lesson 4'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-1470516481280497172</id><published>2007-09-22T14:12:00.001-07:00</published><updated>2007-09-24T02:40:45.676-07:00</updated><title type='text'>NXT Programming - Lesson 3</title><content type='html'>&lt;hr /&gt;Date: 2007.09.20&lt;br /&gt;Duration of activity: 4 hours&lt;br /&gt;Group members: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;Goals of this session:&lt;br /&gt;Trying the lego sound sensor&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Very full lesson!&lt;br /&gt;The first time without any problem and in which all the tools are perfectly arranged!&lt;br /&gt;We start mounting the sensor on the car as described in the building instruction and trying it with the sample programs &lt;span style="font-style: italic;"&gt;SonicSensorTest.java&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;SoundCtrCar.java&lt;/span&gt;. Ok, all is working: it's a lucky day!&lt;br /&gt;We can go on with the second sample program: we think that the best way to check the ESCAPE button state also during the inner loops is to create a ButtonListener instance that modifies the value of a control variable. To make the code more compact we used the method Locomotion.drive instead of specific motion functions (&lt;span style="font-style:italic;"&gt;forward()&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;left()&lt;/span&gt;, ...). The resulting code is the following:&lt;br /&gt;&lt;a href="http://www.daimi.au.dk/~cosenal/legolab/SoundCtrCar.java"&gt;SoundCtrCar.java&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Before going on with the main goal of the lesson, we begin to deal with I/O methods, especially for file writing. The goal is: to sample readings from the sound sensor on a file, download it on the pc and use the recording file to create a graph.&lt;br /&gt;After a quick reading to the lejos API, we make the first attempts: the primary hitch is manage the little amount of memory, because of that the program raises an exception after only three seconds of recording. We trace the amount of free memory during the program execution: the problem doesn't concern the I/O functions, but the operations used to build the strings.&lt;br /&gt;Once solved this problem, found a trick to write string on file and discovered the application to download the file on the pc (thank you Gert!), we code the java implementation of Toledo's experiment:&lt;br /&gt;&lt;a href="http://www.daimi.au.dk/~cosenal/legolab/ClapDetector.java"&gt;ClapDetector.java&lt;/a&gt;&lt;br /&gt;After tuning the threshold value (we set them 10% under Toledo's values), we obtain a really working clap detector!.&lt;br /&gt;What about the sampling on the file? It seems it works, except a little detail:&lt;br /&gt;in the beginning of the recording file we can see some junk characters: &lt;br /&gt;maybe the &lt;span style="font-style:italic;"&gt;flush()&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;close()&lt;/span&gt; functions of lejos implementation aren't still perfect. &lt;br /&gt;After cleaning manually the file, we process it using gnuplot and we obtain this wonderful graph!&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.daimi.au.dk/~cosenal/legolab/clapGraph.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px;" src="http://www.daimi.au.dk/~cosenal/legolab/clapGraph.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Good work, we can go home: this time the gate is open :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-1470516481280497172?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/1470516481280497172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=1470516481280497172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/1470516481280497172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/1470516481280497172'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/09/nxt-programming-lesson-3.html' title='NXT Programming - Lesson 3'/><author><name>zimba</name><uri>http://www.blogger.com/profile/05249586150135171428</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-1743479241364373416</id><published>2007-09-19T08:58:00.000-07:00</published><updated>2007-09-21T02:06:49.397-07:00</updated><title type='text'>NXT Programming - Lesson 2</title><content type='html'>&lt;hr /&gt;Date: 2007.09.13&lt;br /&gt;Duration of activity: 6 hours&lt;br /&gt;Group members: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;Goals of this session:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Trying the lego ultrasonic sensor&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Trying different strategies for wall following systems&lt;/li&gt;&lt;/ol&gt;After having set up our lego workstation on our laptop, we started working on our goals.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5112572915468269730"&gt;&lt;img src="http://lh6.google.it/djjeck/RvOB-qLE-KI/AAAAAAAAAGE/NLzWohd9r5g/s144/IMG_1704_resize.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;We added the ultrasonic sensor to the model, and uploaded the first sample program (Avoider).&lt;br /&gt;&lt;em&gt;Q: What kind of control is it?&lt;/em&gt;&lt;br /&gt;A: A proportional control. It has indeed sudden starts and stops, and it moves jerkily.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Then we rotated the ultrasonic sensor, and tried to upload the second sample program (WallFollower). We soon discovered that there was no sample program, so we rewrote in java the two suggested solutions for it.&lt;/p&gt;&lt;p&gt;We tried the algorithm from the F.G.Martin's book, and it didn't work, since the model rotated too fast, and it often lost the wall, even with the gentle turn patch.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;We then tried the Philippe Hurbain code. We couldn't make it work well, probably because the lego sensor often doesn't see obstacles when their surface is rotated of a too big angle.&lt;/p&gt;&lt;p&gt;After some vain changes to the constants, that only made the robot spin, we thought that we could have done much better by making the robot rotate its "head".&lt;/p&gt;&lt;p&gt;We attached the third motor on the top of the model, with the ultrasonic sensor on it, and wrote an algorithm to make it avoid obstacles while following the wall.&lt;br /&gt;Our code simply made the robot always look toward the wall, and every second rotate the head, sample the distance ahead, and then rotate it back.&lt;/p&gt;&lt;p&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5112572919763237058"&gt;&lt;img src="http://lh3.google.it/djjeck/RvOB-6LE-MI/AAAAAAAAAGU/FhFmpGGm1B0/s144/IMG_1709_resize.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;After many tries, we decided that the rotation of the head was not enough precise to make the head return in the previous position, so we later made the whole model rotate, and not only its head, to avoid the synchronization problem.&lt;/p&gt;Another variation on the algorithm was to make the robot decide, every time it looked around, what was the position in which it was the most parallel to the wall, by choosing the one in which it sampled the shortest distance to it.&lt;br /&gt;&amp;lt;&amp;lt;youtube video coming soon&amp;gt;&amp;gt;&lt;p&gt;The only problem left was that when the robot came across a corner and it didn't see any obstacle, it started spinning around.&lt;br /&gt;We then chose to made the robot describe an arc until it founds something again. To make it be an arc of a circle and not of a spiral, we calculated the speeds of the two wheels, as a function of the expected distance from the wall and the (constant) distance between the two wheels.&lt;/p&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5112573241885784274"&gt;&lt;img src="http://lh6.google.it/djjeck/RvOCRqLE-NI/AAAAAAAAAGc/AhstcpHv2VM/s144/IMG_1712_resize.JPG" /&gt;&lt;/a&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5112573246180751586"&gt;&lt;img src="http://lh3.google.it/djjeck/RvOCR6LE-OI/AAAAAAAAAGk/YcytbFauv3I/s144/IMG_1713_resize.JPG" /&gt;&lt;/a&gt;&lt;p&gt;&lt;br /&gt;Since it was too late, and we were almost satisfied of our work, we forgot writing the lab report (and this is why we're writing it nearly a week later), and after having found someone with the key to open the gate, we went home.&lt;br /&gt;&lt;a href="http://picasaweb.google.it/djjeck/LGLBIT/photo#5112573246180751618"&gt;&lt;img src="http://lh3.google.it/djjeck/RvOCR6LE-QI/AAAAAAAAAG0/cn_0yz8UYPo/s144/IMG_1719_resize.JPG" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-1743479241364373416?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/1743479241364373416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=1743479241364373416' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/1743479241364373416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/1743479241364373416'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/09/date-2007.html' title='NXT Programming - Lesson 2'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-8024768858344305708</id><published>2007-09-06T10:14:00.001-07:00</published><updated>2007-09-07T06:52:20.362-07:00</updated><title type='text'>NXT Programming - Lesson 1</title><content type='html'>&lt;hr /&gt;Date: 2007.08.06&lt;br /&gt;Duration of activity: 4+ hours&lt;br /&gt;Group members participating: Alessandro, Daniela, Samuele&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;This time we brought our CDs so we could start to program the NXT brick.&lt;br /&gt;We took up our laptop and started following the installation guides.&lt;br /&gt;&lt;a href="http://picasaweb.google.dk/djjeck/LGLBIT/photo#5107224467521887778"&gt;&lt;img src="http://lh4.google.dk/djjeck/RuCBmA7TXiI/AAAAAAAAAEE/hqhEyy4qIJQ/s144/IMG_1432.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;Two hours later we were sure that there is no way to install the whole stuff on Windows Vista, so we decided to move to one of the PCs of the labs - now freed up by our course mates gone to home.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a style="font-weight: bold;" href="http://picasaweb.google.dk/djjeck/LGLBIT/photo#5107229033072123474"&gt;&lt;img src="http://lh3.google.dk/djjeck/RuCFvw7TXlI/AAAAAAAAAFQ/4FiIZt4r-Xk/s144/IMG_1433.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.dk/djjeck/LGLBIT/photo#5107224476111822386"&gt;&lt;img src="http://lh6.google.dk/djjeck/RuCBmg7TXjI/AAAAAAAAAEQ/j2iS8bale-o/s144/IMG_1437.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;We then installed and set up Eclipse, to make it compile and transfer programs.&lt;br /&gt;Of course nothing works, at first because of Eclipse weird behaviour, then because sensors were obviously attached to the wrong port, and at last in finding the little and well hidden button under the USB port.&lt;/p&gt;&lt;p&gt;&lt;a href="http://picasaweb.google.dk/djjeck/LGLBIT/photo#5107234784033332834"&gt;&lt;img src="http://lh6.google.dk/djjeck/RuCK-g7TXmI/AAAAAAAAAFY/Nn6lovgLM5M/s144/IMG_1442.JPG" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;At 18.44, we have our first moving robot (with only the sample program inside)&lt;br /&gt;&lt;a href="http://picasaweb.google.dk/djjeck/LGLBIT/photo#5107227336560041538"&gt;&lt;img src="http://lh4.google.dk/djjeck/RuCENA7TXkI/AAAAAAAAAEw/m3kxiZKzpcI/s144/it%20works.PNG" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Then we tried some modifications to the code:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;We changed the sampling speed, which had nearly no effect.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;We increased the speed, but not to much, to avoid big swings.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;We implemented the three states controller, which obviously could not work with the LineFollower environment (but we were starting to get too tired to noticed it before trying).&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://picasaweb.google.dk/djjeck/LGLBIT/photo#5107234844162874994"&gt;&lt;img src="http://lh4.google.dk/djjeck/RuCLCA7TXnI/AAAAAAAAAFg/PbCgXTsji2M/s144/IMG_1449.JPG" /&gt;&lt;/a&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;We finally implemented the gentle turn, which actually worked better, at least for the black lines that we used.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;And since the sun went down while trying, we even experienced how sensors are influenced by the changes of ambient light.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;At the end, we just kept playing with lego bricks, and trying some other sensors or model designs without success. We'll be more lucky next time.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Quote of the day:&lt;br /&gt;(While dictating a PIN code)&lt;br /&gt;&lt;i&gt;- "5... 5... 2..."&lt;br /&gt;- "Uppercase or lowercase?"&lt;/i&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-8024768858344305708?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/8024768858344305708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=8024768858344305708' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/8024768858344305708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/8024768858344305708'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/09/nxt-programming-lesson-1.html' title='NXT Programming - Lesson 1'/><author><name>djjeck</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_1fcsS7Xs5B4/TTd1heVNYvI/AAAAAAAAGv0/Th9vkts3rc4/S220/logo%2Bwhite%2Bbackground.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032316157388116048.post-4180570703698450610</id><published>2007-09-04T18:04:00.000-07:00</published><updated>2007-09-06T08:25:35.969-07:00</updated><title type='text'>NXT Programming - prelesson</title><content type='html'>We opened the two boxes ("Hooray!"), and started to get confused with the pieces.&lt;br /&gt;So the first thing was sorting pieces in those small compartments.&lt;br /&gt;While sorting, because of our impatience, we also started to build the car model described in the manual.&lt;br /&gt;After about one hour we ended up with the complete first stage of the model, and all pieces were in their right place.&lt;br /&gt;We forgot CDs and battery adapter at home, so we couldn't proceed and went home sadly *SIGH*.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032316157388116048-4180570703698450610?l=legolab-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://legolab-it.blogspot.com/feeds/4180570703698450610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9032316157388116048&amp;postID=4180570703698450610' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/4180570703698450610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032316157388116048/posts/default/4180570703698450610'/><link rel='alternate' type='text/html' href='http://legolab-it.blogspot.com/2007/09/nxt-programming-prelesson.html' title='NXT Programming - prelesson'/><author><name>zimba</name><uri>http://www.blogger.com/profile/05249586150135171428</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
