Home > Articles

This chapter is from the book

Creating a Navigator Robot

Let's build a robot so we can try out some simple navigation. Tippy seems like it could be good for navigation, because it rotates within its own footprint, but in fact Tippy is too fast! Fast robots like Tippy are actually not good for timing navigation because the wheels skid when starting and stopping. Also, it takes Tippy a few milliseconds to build up enough force to start moving, which can throw off our timing measurements. What we need is a robot that doesn't skid and starts moving immediately when it is instructed to move. Slow rotation is vital, so for this chapter we will build a robot that uses tank treads to achieve differential steering.

Building the Trilobot

This section shows you how to build a robot using tank treads. The robot moves relatively slowly, and makes slow turns, making it ideal for use with the TimingNavigator class. The robot is named Trilobot because it resembles an extinct animal known as a trilobite (Figure 7–7). Both trilobot and trilobite have wraparound antennae, they are low to the ground, they have a hard outer shell, and both have arthropod-level intelligence.

Figure 7-7Figure 7–7 Trilobite vs. Trilobot.


Step 1Step 1 Join two 16-unit beams together with two 8-unit axles, spacing them with a bush. Repeat the same for the other side.


Step 2Step 2 Clamp three 2 × 8 plates to the underside of the chassis, joining the two halves together. The front plate should hang over the edge by one unit.


Step 3Step 3 Attach two touch sensors and two 1 × 2 beams with axle connectors to the front plate.


Step 4Step 4 Clamp a 2 × 8 plate over the assemblage. Insert two 3-unit axles into the green axle connectors.


Step 5Step 5 Attach two axle connectors to the front of the robot and insert two axle pins into the top. These will be used to support the front bumper.


Step 6Step 6 Attach two black lift arms to the axle pins. At this point they should swing freely.


Step 7Step 7 Attach two dark gray 3/4 pins in the hole closest to the axle pins. These will be used to secure a bar to keep the bumpers from moving forward too much. Next, insert two axle pins to the underside of the bumper.


Step 8Step 8 Attach two 8-unit gears to the axle pins on the underside of the bumper. Clip on the 5-unit lift arm, which will act as a restraining bar for the bumper. This will allow the bumpers some movement back and forth without swinging all the way out.


Step 9Step 9 Attach two bushes to each of the two front axles. On the rear axles, attach a 24-tooth gear and a bush.


Step 10Step 10 Attach four friction pins to the outer beams. These will be used to secure the RCX brick to the chassis.


Step 11Step 11 Clamp the RCX brick to the top of the chassis. Make sure it fits snugly to the top of the beams. Insert four 3/4 pins into the holes of the RCX brick.


Step 12Step 12 Attach four securing beams to the sides of the robot to lock the RCX down.


Step 13Step 13 Place a rubber tread over two sprocket wheels and insert the wheels onto a pair of axles. Repeat for the other side.


Step 14Step 14 Secure the front sprocket wheels with Technic bushes. The rear sprocket wheels should be secured with 16-tooth gears, which will cause the wheel to turn with the motorized axle.


Step 15Step 15 Attach two 1 × 8 plates to the rear of the chassis. This prepares a surface to clamp down two motors, as the bottom of the motor is not flat.


Step 16Step 16 Attach a 16-tooth gear to each motor, then attach them to the rear of the chassis, back to back.


Step 17Step 17 Attach two 2 × 4 plates across the gap between the two motors (difficult to see in this picture). On top of these plates, attach two more 2 × 4 plates perpendicular to the first pair. This provides added strength to the unit.


Step 18Step 18 Attach two 2 × 6 plates to the top of the robot. This secures the motors in place when force is applied to the gears.


Step 19Step 19 Attach two short wire bricks to the front sensors, keeping the wires to the outer sides of the robot. Attach two more short wire bricks to the rear motors, with the wires facing outward. When you attach the wires to Ports A and C, make sure the wires face inward.


Programming Trilobot

Now that we have the Trilobot built, it is time to give it some intelligent navigation abilities. TimingNavigator requires us to figure out how long it takes to travel one meter, and how long it takes to rotate 360 degrees. The first part is easy; all we need to do is make a simple program to get it moving forward and then time it:

import josx.platform.rcx.*;
class TravelTest {
  public static void main(String [] args) {
   Motor.A.setPower(7); // Change to equalize motors
   Motor.C.setPower(7); // Change to equalize motors
   Motor.A.forward();
   Motor.C.forward();
  }
}

This code has two lines for setting the power to each motor. Generally the motors do not produce the same torque, which can cause your robot to veer off in one direction. When I first tested Trilobot, it veered off significantly to the left, indicating that Motor C is turning faster than Motor A. By playing around with the aPower argument in the setPower() method, I came up with the following revised code:

import josx.platform.rcx.*;
class TravelTest {
  public static void main(String [] args) {
   Motor.A.setPower(7);
   Motor.C.setPower(4); // Decreases power
   Motor.A.forward();
   Motor.C.forward();
  }
}

It is very important to balance the two motors! If they are not balanced the robot will be thrown off course. Now we need to create a small track for Trilobot by measuring out a meter (100 cm) on the floor. If you want, you can measure out 100 inches if you are more comfortable using the imperial system of measurement, but just make sure you consistently use inches with all measurements. If you use inches in the constructor, the TimingNavigator class will use inches for the x and y coordinates.

For better accuracy, instead of measuring 100 units, you can measure out 400 units, and then divide the final result by four to get the average. Keep in mind the surface the robot travels on affects speed. My test on a carpet produced different times than when it was done on a hard surface. The total four meter trip took 21.9 seconds on carpet, so we will use the value of 5.475 seconds per meter. Next, we need to measure the time it takes to rotate 360 degrees. For this, I'm going to make it rotate four times and average them out. The code is the same as the previous example, only one of the motors will move backward:

import josx.platform.rcx.*;
class RotateTest {
  public static void main(String [] args) {
   Motor.A.setPower(7);
   Motor.C.setPower(4); // Decreases power
   Motor.A.forward();
   Motor.C.backward();
  }
}

Four complete rotations took 16.0 seconds, so one rotation is about 4.0 seconds. I also tried rotating counterclockwise to see if it produced a different result, but it was quite similar at 16.27 seconds for four rotations, or 4.0675 seconds per rotation. I'll use a final average of 4.03 seconds. Now that we have our two required values we can create a TimingNavigator object and try some simple functions.

Our first test will make Trilobot spin 360 degrees (so we can see how accurate we were with the calibrations), then trace out the shape of a square. The path will look similar to Figure 7–8. To trace the square, we will make it go to the following coordinates: (100,0) (100,100) (0,100) (0,0):

Figure 7-8Figure 7–8 Test path for Trilobot.

	1.	import josx.platform.rcx.*;
	2.	import josx.robotics.*;
	3.	
	4.	class Trilobot {
	5.	
	6.	  public static void main(String [] args) {
	7.	   Motor.A.setPower(7);
	8.	   Motor.C.setPower(5);
	9.	
	10.	   TimingNavigator n = new TimingNavigator(Motor.C, Motor.A, 5.475f, 4.03f);
	11.	   n.rotate(360);
	12.	   n.gotoPoint(100,0);
	13.	   n.gotoPoint(100,100);
	14.	   n.gotoPoint(0,100);
	15.	   n.gotoPoint(0,0);
	16.	  }
	17.	}

WARNING

The third and fourth parameters in this constructor will likely be different for you than the values here (5.475 and 4.03). These values are dependent on the motor strengths and battery charge of your robot. If your robot uses lithium batteries the wheels will probably turn faster, so the parameters in the constructor will likely be smaller than for a robot that uses rechargeable batteries.

In this code we have retained the method calls to setPower() to equalize the motors. If all goes well the robot should complete a full square and then stop. If you notice that Trilobot rotates more than 360 degrees, you might want to consider lowering the rotate argument in the TimingNavigator constructor; likewise, if it doesn't rotate enough it should be increased. Once this is straightened out as close as possible (it will never be perfect) we can move on to some more serious programming using behavior control.

In this example, and the rest of the book, we use behavior control as the architecture for robotics programming. Behavior programming gets a little more challenging with high-level classes such as Navigator, but not much more. Trilobot will have four behaviors it will use to navigate. The lowest level behavior will randomly go from one point to another within a square 150 × 150 cm (Figure 7–9). At any time while the robot is moving to a point, if one of the bumpers hits an object it reacts, based on the bumper. If the left bumper detects an object, the robot backs up 20 cm and makes a buzz. If the right bumper detects an object, the robot backs up 20 cm and makes a beep. After more than 30 seconds elapse, the robot makes a sound then returns to the point of origin, stops, and pauses for five seconds before continuing. Each one of these reactions will be in a separate Behavior object (Table 7–1), and each behavior will share the same Navigator object for its own purposes to keep track of coordinates. In this example it will be interesting to place a reference object, such as a dime, at the point of origin to see how close it comes after 30 seconds.

Figure 7-9Figure 7–9 Trilobot confines itself to a square.

Table 7-1 Behavior Descriptions for Trilobot

Condition

Action

Suppress

Always

Move to random points within a square region

Stop traveling and update coordinates

Left bumper collision

Make noise and back up 20 cm

Stop moving backward

Right bumper collision

Make noise and back up 20 cm

Stop moving backward

30 seconds

Seek point of origin

Stop moving to origin


Let's begin with the lowest level behavior first. We use the TimingNavigator class to control all operations in all classes. The method gotoPoint() will serve our purpose of moving about randomly within a square 1.5 m × 1.5 m, as follows:

	1.	import josx.robotics.*;
	2.	public class Move implements Behavior {
	3.	  private boolean active; // Indicates behavior is active
	4.	  private Navigator nav;
	5.	  
	6.	  public Move(Navigator nav) {
	7.	   this.nav = nav;
	8.	   active = false;
	9.	  }
	10.	
	11.	  public boolean takeControl() {
	12.	   return true;
	13.	  }
	14.	
	15.	  public void suppress() {
	16.	   active = false;
	17.	   nav.stop();
	18.	  }
	19.	  
	20.	  public void action() {
	21.	   active = true;
	22.	   while(active) {
	23.	     float x = (int)(Math.random() * 150);
	24.	     float y = (int)(Math.random() * 150);
	25.	     nav.gotoPoint(x, y);
	26.	   }
	27.	  }
	28.	}

Notice this class uses an instance of TimingNavigator in the constructor. This object will be shared by many behaviors. The main action for the Move behavior takes place starting at Line 20. The while loop will repeat until active is false, which will occur as soon as suppress() is called. The suppress() method also stops the robot by calling Navigator.stop(), and the Navigator object automatically updates the internal positional coordinates when this occurs. Now let's create some classes to handle collisions with other objects.

The Trilobot robot has two separate touch sensors, one for the left bumper and one for the right bumper. The code actually reacts the same for the left and right bumpers, so only one bumper is necessary for this program, but I included a split bumper so that Trilobot could be reprogrammed with more interesting behavior based on the side the collision occurred on. For the purposes of this program, we want Trilobot to stop and back up when a collision occurs. The suppress() code will stop Trilobot backing up, and the takeControl() method will only take control when the bumper hits an object. We use a SensorListener, as described in the previous chapter, so collisions are never missed. The left bumper behavior is as follows:

	1.	import josx.robotics.*;
	2.	import josx.platform.rcx.*;
	3.	
	4.	public class LeftBump implements Behavior, SensorListener {
	5.	  private Navigator nav;
	6.	  private boolean hasCollided;
	7.	  
	8.	  public LeftBump(Navigator nav) {
	9.	   this.nav = nav;
	10.	   hasCollided = false;
	11.	   Sensor.S1.addSensorListener(this);
	12.	  }
	13.	  
	14.	  public boolean takeControl() {
	15.	   if(hasCollided) {
	16.	     hasCollided = false; // reset value
	17.	     return true;
	18.	   } else
	19.	     return false;
	20.	  }
	21.	  
	22.	  public void suppress() {
	23.	   nav.stop();
	24.	  }
	25.	  
	26.	  public void stateChanged(Sensor bumper, int oldValue, int newValue) {
	27.	   if(bumper.readBooleanValue() == true)
	28.	     hasCollided = true;
	29.	  }
	30.	  
	31.	  public void action() {
	32.	   // Back up:
	33.	   Sound.buzz();
	34.	   nav.travel(-20);
	35.	  }
	36.	}

This code is quite straightforward. When the touch sensor is hit, Line 28 changes the hasCollided value to true. Then, when takeControl() is called the method returns true. Line 16 resets the hasCollided flag. Likewise, the right bumper behavior is almost identical:

	1.	import josx.robotics.*;
	2.	import josx.platform.rcx.*;
	3.	
	4.	public class RightBump implements Behavior, SensorListener {
	5.	  private Navigator nav;
	6.	  private boolean hasCollided;
	7.	  
	8.	  public RightBump(Navigator nav) {
	9.	   this.nav = nav;
	10.	   hasCollided = false;
	11.	   Sensor.S3.addSensorListener(this);
	12.	  }
	13.	  
	14.	  public boolean takeControl() {
	15.	   if(hasCollided) {
	16.	     hasCollided = false; // reset value
	17.	     return true;
	18.	   } else
	19.	     return false;
	20.	  }
	21.	  
	22.	  public void suppress() {
	23.	   nav.stop();
	24.	  }
	25.	  
	26.	  public void stateChanged(Sensor bumper, int oldValue, int newValue) {
	27.	   if(bumper.readBooleanValue() == true)
	28.	     hasCollided = true;
	29.	  }
	30.	  
	31.	  public void action() {
	32.	   // Back up:
	33.	   Sound.beep();
	34.	   nav.travel(-20);
	35.	  }
	36.	}

Our fourth behavior is the most complex of all. It requires the robot to go back to the point of origin when 30 seconds have elapsed. To do this, we will use the josx.util.Timer class and the josx.util.TimerListener interface. TimerListener will be notified by the timer every 30 seconds via the timedOut() method. We'll make our behavior implement TimerListener, and the timedOut() method will simply change a Boolean value to indicate the time is up, as follows:

	1.	  public void timedOut() {
	2.	   timeUp = true;
	3.	  }
The takeControl() method will then return true only if the time is up:
	1.	  public boolean takeControl() {
	2.	   return timeUp;
	3.	  }

The action() method is very easy to implement. It simply calls the method gotoPoint(0,0) to make Trilobot return to the point of origin. The completed module for this behavior is as follows:

	1.	import josx.robotics.*;
	2.	import josx.platform.rcx.*;
	3.	import josx.util.*;
	4.	
	5.	public class GoHome implements TimerListener, Behavior {
	6.	  
	7.	  Navigator nav;
	8.	  boolean timeUp;
	9.	  
	10.	  public GoHome(Navigator nav) {
	11.	   this.nav = nav;
	12.	   timeUp = false;
	13.	   Timer t = new Timer(30000, this);
	14.	   t.start();
	15.	  }
	16.	  
	17.	  public void timedOut() {
	18.	   timeUp = true;
	19.	  }
	20.	  
	21.	  public boolean takeControl() {
	22.	   return timeUp;
	23.	  }
	24.	  
	25.	  public void suppress() {
	26.	   nav.stop();
	27.	  }
	28.	  
	29.	  public void action() {   
	30.	   Sound.beepSequence();
	31.	   nav.gotoPoint(0,0);
	32.	   Sound.twoBeeps();
	33.	   try {Thread.sleep(5000);}catch(InterruptedException e) {}
	34.	   Sound.beep();
	35.	   timeUp = false; // reset time up   
	36.	  }
	37.	}

As you can see, the methods are all very simple and straightforward. Now we merely need to create a main class to start the process:

	1.	import josx.platform.rcx.*;
	2.	import josx.robotics.*;
	3.	
	4.	class TrilobotMain {
	5.	  public static void main(String [] args) {
	6.	   Motor.A.setPower(7);
	7.	   Motor.C.setPower(5);
	8.	   TimingNavigator nav = new TimingNavigator(Motor.C, Motor.A, 5.475f, 4.03f);
	9.	   
	10.	   Behavior b1 = new Move(nav);
	11.	   Behavior b2 = new LeftBump(nav);
	12.	   Behavior b3 = new RightBump(nav);
	13.	   Behavior b4 = new GoHome(nav);
	14.	   
	15.	   Behavior [] bArray = {b1, b2, b3, b4};
	16.	   Arbitrator arby = new Arbitrator(bArray);
	17.	   arby.start();
	18.	  }
	19.	}

WARNING

Lines 6, 7, and 8 should be tailored to your specific robot. These variables are dependent on relative motor strengths, battery level, and other factors.

That's it! Notice all four Behavior objects share the same Navigator object (nav). Little by little we have built up many simple steps to create some relatively complex behavior. Upload the code to Trilobot and see how well it performs. Hopefully, after 30 seconds, Trilobot will come close to the point of origin. Now let's examine the accuracy of the results we can achieve with TimingNavigator.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020