<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>pathbot &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/pathbot/</link>
	<description>Feed of posts on WordPress.com tagged "pathbot"</description>
	<pubDate>Tue, 21 May 2013 12:34:08 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Follow Lines &ndash; Fork in the Road]]></title>
<link>http://roachnet.wordpress.com/2010/03/14/follow-lines-fork-in-the-road/</link>
<pubDate>Mon, 15 Mar 2010 05:28:00 +0000</pubDate>
<dc:creator>Thom Roach</dc:creator>
<guid>http://roachnet.wordpress.com/2010/03/14/follow-lines-fork-in-the-road/</guid>
<description><![CDATA[**Repost from an article I posted on Mindsensors forums last year. People have asked me to provide m]]></description>
<content:encoded><![CDATA[<p>**Repost from an article I posted on Mindsensors forums last year.</p>
<p>People have asked me to provide more information about my video on the Mindsensors site about testing the<strong> Line Leader sensor</strong>. How can the robot make a choice at a fork in the road (line)?     <br />My Video: <a href="http://www.youtube.com/watch?v=isf2Kz_jdrA">http://www.youtube.com/watch?v=isf2Kz_jdrA</a>     <br />First, let’s expand on the problem. I found an interesting video a while back on YouTube.com for a Robocup Jr – Rescue competition that outlined some fairly complex rules for following a line to a destination. In short, there are 10+ line configurations that a robot must be able to navigate in order to complete the mission. There is much more to this mission, but the focus here is on following the lines&#8230;     <br />Robocup Jr Video: <a href="http://www.youtube.com/watch?v=LUvBfAmUm48">http://www.youtube.com/watch?v=LUvBfAmUm48</a> </p>
<p> <!--more-->  <br />Here is a sample line configuration for the robot to navigate.
</p>
<p>&#160;<a href="http://roachnet.files.wordpress.com/2010/03/pathdecision.jpg"><img style="display:inline;border-width:0;" title="PathDecision" border="0" alt="PathDecision" src="http://roachnet.files.wordpress.com/2010/03/pathdecision_thumb.jpg?w=182&#038;h=131" width="182" height="131" /></a>     <br />One configuration is shown above where the robot must follow the line to a circle, and determine which direction to travel to complete it. Markers are provided indicating the correct (suggested) route to follow. Markers on various configuration sheets can be left or right.     <br />I am sure there is some smart robot programmer out there who is saying… “It’s easy with a light sensor or two…” (contact me so I can learn!). The robot somehow needs to determine that it is over a green marker, and turn the robot that direction to continue following the line around the circle to the other side. Sounds easy.     <br />I tried to sense color (light intensity) differences with two NXT light sensors initially, and that works, but light intensity also changes as the robot moves from black line to white surface. To the light sensor, the world is gray-scale and there are no sharp lines. A black line on a white surface looks like this.     <br /><a href="http://roachnet.files.wordpress.com/2010/03/linelightsensor.jpg"><img style="display:inline;border-width:0;" title="LineLightSensor" border="0" alt="LineLightSensor" src="http://roachnet.files.wordpress.com/2010/03/linelightsensor_thumb.jpg?w=244&#038;h=64" width="244" height="64" /></a>     <br />It is difficult to find &#34;green&#34; or the gray-scale equivilent in this mess. Here is a crude drawing of what the marker section might look like to a light sensor.     <br /><a href="http://roachnet.files.wordpress.com/2010/03/markerls.jpg"><img style="display:inline;border-width:0;" title="MarkerLS" border="0" alt="MarkerLS" src="http://roachnet.files.wordpress.com/2010/03/markerls_thumb.jpg?w=244&#038;h=139" width="244" height="139" /></a>     <br />The problem is: How can I distinguish green from the edge of the line? Like I said, I am sure someone out there solved this problem with a light sensor or two, but not me. I implemented the Line Leader sensor to solve the problem. Because I have an array of 8 light sensors, and the Line Leader is great at keeping me on the line, I decided that might be able to use the width of the line as an indicator that I am over a marker.     <br />Knowing the line width should be 2 or 3 detectors wide, I figured there must be a way to determine If the line became wider (over a line and marker). Since the green marker may or may not be detected as part of the line, I implemented custom code to read the raw values from each detector in the Line Leader to compare and calculate my own conclusions.     <br />&#160;<a href="http://roachnet.files.wordpress.com/2010/03/markerlsline.jpg"><img style="display:inline;border-width:0;" title="MarkerLS-Line" border="0" alt="MarkerLS-Line" src="http://roachnet.files.wordpress.com/2010/03/markerlsline_thumb.jpg?w=244&#038;h=139" width="244" height="139" /></a> </p>
<p><a href="http://roachnet.files.wordpress.com/2010/03/markerlsmarker.jpg"><img style="display:inline;border-width:0;" title="MarkerLS-Marker" border="0" alt="MarkerLS-Marker" src="http://roachnet.files.wordpress.com/2010/03/markerlsmarker_thumb.jpg?w=244&#038;h=139" width="244" height="139" /></a>     <br />During initialization, I read the WHITE THRESHOLD values into memory. As the robot follows the line, it also compares the raw values to the white threshold values. If more four or more detectors of the eight are dark, the robot must be over a marker. A little more math is used to determine which side of the line leader has encountered the marker and the robot turns that direction.</p>
<dl>
<dt>Code: <a href="http://www.mindsensors.com/forums/viewtopic.php?f=6&#38;t=14#">Select all</a></dt>
<dd><code>void BEH_LineMarker() {        <br />&#160; byte i;         <br />&#160; byte tL = 0;         <br />&#160; byte tR = 0;         <br />&#160;&#160;&#160;&#160;&#160; LLReadSensorRaw(LineLeaderPort, llRaw);         <br />&#160;&#160;&#160;&#160; for (i=0; i&#60;4; i++) {&#160;&#160; //COMPARE THE LEFT SIDE OF THE LINE LEADER         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (llRaw.arr[i] &#60; llWhite.arr[i]){         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tL++;         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }         <br />&#160;&#160;&#160;&#160;&#160; }         <br />&#160;&#160;&#160;&#160;&#160; for (i=4; i&#60;8; i++) {&#160; //COMPARE THE RIGHT SIDE OF THE LINE LEADER         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (llRaw.arr[i] &#60; llWhite.arr[i]){         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tR++;         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }         <br />&#160;&#160;&#160;&#160;&#160; }         <br />&#160;&#160;&#160;&#160;&#160; if (tL+tR &#62;= 4) {&#160; //ARE THERE ENOUGH DETECTORS TRIGGERED TO MEAN WE FOUND A MARKER?         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DriveCommand(MARKER_SPEED,sgn(tR-tL)*90,BEHAVIOR_LINE_MARKER);&#160; //RIGHT (POSITIVE), LEFT (NEGITIVE)         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RequestControl(BEHAVIOR_LINE_MARKER);         <br />&#160;&#160;&#160;&#160;&#160; }         <br />&#160;&#160;&#160;&#160;&#160; else         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DeclineControl(BEHAVIOR_LINE_MARKER);         <br />}         <br /></code></dd>
</dl>
<p>When called, this code reads the raw values into llRaw.arr for each of the 8 detectors in the Line Leader. As it compares to the white threshold values, it updates the left or right counters. At the end of comparison, if more than 4 detectors see dark, we must be over a marker, so&#8230; If most of the detections where on the right, turn right. If most of the detections were on the left, turn left.   <br />RequestControl() and DeclineControl() are behavior-based fucntions that determine if this behavior wants to control the motors or not. More in another post&#8230;.   </p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Follow a Line &ndash; Line Following Basics]]></title>
<link>http://roachnet.wordpress.com/2009/08/31/follow-a-line-line-following-basics-2/</link>
<pubDate>Tue, 01 Sep 2009 04:14:00 +0000</pubDate>
<dc:creator>Thom Roach</dc:creator>
<guid>http://roachnet.wordpress.com/2009/08/31/follow-a-line-line-following-basics-2/</guid>
<description><![CDATA[Summary There are many ways (and sensors) available that can allow a robot to follow a line. I have]]></description>
<content:encoded><![CDATA[<h2>Summary</h2>
<p>There are many ways (and sensors) available that can allow a robot to follow a line. I have experimented a few that are of interest.</p>
<ul>
<li>Single Light Sensor</li>
<li>Two Light Sensors</li>
<li>Mindsensors LineLeader Sensor (Intelligent array of 8 light sensors in one I2C package)</li>
</ul>
<p>In this article I review a couple of standard ways of staying on track, and then review the new Mindsensors – Line Leader sensor.  I was part of a beta-testing group for this great sensor.</p>
<p><!--more--></p>
<h2>Single Light Sensor</h2>
<p>Using on NXT light sensor, there</p>
<p>are a couple of possibilities for following a line that can be effective. The programmer can either code to follow the line itself, or the edge of the line.</p>
<p><a href="http://roachnet.files.wordpress.com/2010/03/clip_image001.gif"><img style="display:inline;border-width:0;" title="clip_image001" src="http://roachnet.files.wordpress.com/2010/03/clip_image001_thumb.gif?w=200&#038;h=39" border="0" alt="clip_image001" width="200" height="39" /></a></p>
<p>Following inside the line offers the advantage of knowing the robot is on the line, but what direct do we turn of we fall off? If the robot falls off of the line, which direction should it turn to return to it? As the robot drifts back and forth on the line, the programmer must try to correct its course to stay on the line. This method is mostly impractical.</p>
<p><a href="http://roachnet.files.wordpress.com/2010/03/clip_image0014.gif"><img style="display:inline;border-width:0;" title="clip_image001[4]" src="http://roachnet.files.wordpress.com/2010/03/clip_image0014_thumb.gif?w=199&#038;h=50" border="0" alt="clip_image001[4]" width="199" height="50" /></a></p>
<p>Edge following offers the advantage of knowing the direction to turn in order to stay on the line. It is generally a faster, more accurate method for following a line. You select the right or left side of the line to follow, and code the robot to turn left if the light sensor reports BLACK and right if WHITE. This method allows a robot to follow the edge of the line through straight sections and curves. Is there a better method to follow a line?</p>
<h2>Two Light Sensors</h2>
<p>Using two NXT light sensors, there are also a couple of useful configurations to review. Sensors are generally set side by side on the front of the robot with either both inside, or both outside the line. With two sensors (left and right), more accurate line following can be achieved because as a line is lost on one side or the other, recovery is possible because we know which side lost the line. <a href="http://roachnet.files.wordpress.com/2010/03/clip_image0016.gif"><img style="display:inline;border-width:0;" title="clip_image001[6]" src="http://roachnet.files.wordpress.com/2010/03/clip_image0016_thumb.gif?w=200&#038;h=74" border="0" alt="clip_image001[6]" width="200" height="74" /></a></p>
<p>Placement of the light sensors is very important so that only one sensor at a time could be on the line. As can be seen in the illustration, as the robot drifts from one side to the other, one sensor contacts the line and the robot can react accordingly.</p>
<p><a href="http://roachnet.files.wordpress.com/2010/03/clip_image0018.gif"><img style="display:inline;border-width:0;" title="clip_image001[8]" src="http://roachnet.files.wordpress.com/2010/03/clip_image0018_thumb.gif?w=214&#038;h=75" border="0" alt="clip_image001[8]" width="214" height="75" /></a></p>
<p>Coding is similar to using one light sensor following the edge of a line, but you can let the robot run straight if both report WHITE or both report BLACK (depending on the configuration). This allows the robot to gain speed instead of oscillating back and forth (as much) as it must with one light sensor.</p>
<h2>Mindsensors Line Leader Sensor</h2>
<p>A more advanced method for following a line is to utilize three or more light sensors to follow a line. Many people have custom built line following sensor arrays, but Mindsensors has just released the Line Leader sensor for the rest of us. Not only does it contain eight (8) sensors in its array, the intelligent sensor also implements some very nice internal coding and a robust I2C interface to communicate with the robot.</p>
<table cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="100%"></td>
</tr>
<tr>
<td><a href="http://roachnet.files.wordpress.com/2010/03/clip_image00110.gif"><img style="display:inline;border-width:0;" title="clip_image001[10]" src="http://roachnet.files.wordpress.com/2010/03/clip_image00110_thumb.gif?w=170&#038;h=153" border="0" alt="clip_image001[10]" width="170" height="153" /></a></td>
<td><a href="http://roachnet.files.wordpress.com/2010/03/clip_image00112.gif"><img style="display:inline;border-width:0;" title="clip_image001[12]" src="http://roachnet.files.wordpress.com/2010/03/clip_image00112_thumb.gif?w=170&#038;h=153" border="0" alt="clip_image001[12]" width="170" height="153" /></a></td>
</tr>
</tbody>
</table>
<p>Because there are 8 light detectors under the sensor, it is very easy to determine how to follow a line. The goal is to keep the line centered under the sensor. As the line moves left or right under the robot, it can compensate to center the line under the sensor. How is this done? Mindsensors has a good explanation in the Line Leader user guide.</p>
<p>Mindsensors took all of the hard work and math out of determining how to follow the line. There is a register for retrieving the STEERING value from the sensor. I have used the STEERING value successfully by supplying speed values to two motors. The following example code shows how to read the STEERING value from the sensor, and apply it to two drive <a href="http://roachnet.files.wordpress.com/2010/03/image.png"><img style="display:inline;margin-left:0;margin-right:0;border-width:0;" title="image" src="http://roachnet.files.wordpress.com/2010/03/image_thumb.png?w=238&#038;h=178" border="0" alt="image" width="238" height="178" align="right" /></a>motors.</p>
<pre class="csharpcode"><span class="kwrd">int</span> clip(<span class="kwrd">int</span> x, <span class="kwrd">int</span> min, <span class="kwrd">int</span> max) {
  <span class="kwrd">if</span> (x&#60;min)
    <span class="kwrd">return</span> min;
  <span class="kwrd">else</span> <span class="kwrd">if</span> (x&#62;max)
    <span class="kwrd">return</span> max;
  <span class="kwrd">else</span>
    <span class="kwrd">return</span> x;
}

While(<span class="kwrd">true</span>) {
<span class="rem">//TWO MOTORS – DIFFERENTIAL DRIVE STEERING FROM LINE LEADER </span>
<span class="rem">//GET STEERING FEEDBACK FROM THE SENSOR TO KEEP ROBOT ON THE LINE</span>

  steering = (<span class="kwrd">int</span>) LL_Read(SensorPort, LineLeaderAddr, LL_READ_STEERING);
  motor[RIGHTMOTOR] = clip(70 + steering, -100, 100); <span class="rem">//RIGHT MOTOR</span>
  motor[LEFTMOTOR] = clip(70 - steering, -100, 100); <span class="rem">//LEFT MOTOR</span>
}</pre>
<p>The clip function is a simple utility function that should be in everyone’s toolbox. It takes value returns it if it is between min and max. If outside the range, it returns min or max.</p>
<p>Mindsensors supplies a simple driver file that makes reading the STEERING value easier. We call LL_Read() with the LL_READ_STEERING constant to return the STEERING value suggested by the sensor based on where the line is. The last step is to determine speed value for the left and right motors. We ideally (in this case) want to travel straight at speed = 70. We add the steering value to the right motor, and subtract it from the left motor (within the range motors accept – [-100 to 100]). That’s it.</p>
<p>As the line drifts to the right (or robot to the left), steering becomes a negative number. The further it moves to the right, the bigger the number becomes to allow for correction of the robot.</p>
<p>If the STEERING value returned is -20, we set the motors to use the value to correct the robot’s steering.</p>
<p>RIGHTMOTOR power = 70 + (-20) = <strong>50</strong></p>
<p>LEFTMOTOR power = 70 – (-20) =<strong> 90</strong></p>
<p>This causes the right motor to spin faster than the left turning the robot left to re-center the sensor over the line.</p>
<p>Your program would continue to loop, finding the next steering value and correcting the motors accordingly. The robot uses this feedback control to follow a line.</p>
<p>What if the robot takes advantage of the NXTs motor implementation and links the RIGHTMOTOR and LEFTMOTOR together? NXT firmware allows the motors to take advantage of the internal encoding for each motor to keep them running at the same speed (It can move in a straight line!). I often implement my drive motors with this configuration so the robot can easily move straight. Here is a quick code sample of implementing sync’d motors.</p>
<pre class="csharpcode"><span class="kwrd">void</span> _DriveRobot(<span class="kwrd">int</span> power, <span class="kwrd">int</span> steering) {
  <span class="kwrd">if</span> (steering &#62;= 0) { <span class="rem">//RIGHT TURN or STRAIGHT</span>
    <span class="kwrd">if</span> (lastPower!=power &#124;&#124; lastSteering != steering){
      nSyncedMotors = synchBA;
      nSyncedTurnRatio = (100 - (2*abs(steering)));
      motor[LEFTMOTOR]=power;
      lastPower=power;
      lastSteering=steering;
    }
  }
  <span class="kwrd">else</span> { <span class="rem">//LEFT TURN</span>
    <span class="kwrd">if</span> (lastPower!=power &#124;&#124; lastSteering != steering){
      nSyncedMotors = synchAB;
      nSyncedTurnRatio = (100 - (2*abs(steering)));
      motor[RIGHTMOTOR]=power;
      lastPower=power;
      lastSteering=steering;
    }
  }
}</pre>
<p>In this case, I have directly passed the STEERING value returned from the Line Leader to this routine with excellent success. Robot speed is determined by the POWER parameter (-100 to 100) to implement reverse, stop, or forward. The STEERING parameter (-100 to 100) determines left, straight, or right turns.</p>
]]></content:encoded>
</item>

</channel>
</rss>
