Showing posts with label NXT. Show all posts
Showing posts with label NXT. Show all posts

Saturday, 7 May 2016

Maze Solver - LeJOS

In this maze solver the robot follows a left hand rule as given in https://embedjournal.com/shortest-path-line-follower-robot-logic-revealed/. The program works in two phases. In the first phase, the robot samples the entire path, stores the x and y co-ordinates of the path and creates a map of maze in the memory. Given two consecutive points, the program also calculates and stores the direction of the robot at each point.  Then the program calculates the shortest path by cancelling out the U turn samples and the samples in opposite directions. In the second phase, the robot actually follows the shortest path. During path following, the robot samples the path again and whenever the direction of two consecutive points falls apart from the expected direction (which we got in the first phase) the robot aligns its direction accordingly.


Let me go through the program logic for shortest-path-finding and shortest-path-following in detail. However, before going through it, it would be better to read the article about Limited Maze Solver in order to understand the high level code structure that I have followed. Let us go through the robot path below and mark the path with directions and corresponding sample numbers in those directions. 



Let us assume that the robot path has the following directions and samples along each of them, when the robot traverses it in the first phase: (In real life, the number of samples may differ when the robot traverses, but the high level logic remains the same)

[North (20), West (10), South (30), East (30), North (35), South (20), East (15), North (40), West (20), East (20), North (20), West (20), East (20), North (25), West (20), East (20), South (25 + 20 + 40 + 20 = 105)]

According to the left-hand-rule in the reference site above, we will further reduce the samples where we have East-West and North-South directions in pairs. This is quite simple to understand, as when the robot traverses to North and then comes to South along the same path, the efforts of traversing eventually cancel out. Same for the directions East-West. After cancelling the opposite direction efforts in the first iteration, the path and the samples look like below. 

[North (20), West (10), South (30), East (30), North (15), East (15), North (40), North (20), North (25), South (25 + 20 + 40 + 20 = 105)]

We will then perform the second iteration of cancellation of East-West and North-South. Below is the result after second iteration.  

[North (20), West (10), South (30), East (30), North (15), East (15), North (40), North (20), South (20 + 40 + 20 = 80)]

We will then perform the third iteration of cancellation of East-West and North-South. Below is the result after third iteration.  

[North (20), West (10), South (30), East (30), North (15), East (15), North (40), South (40 + 20 = 60)]

We will then perform the fourth iteration of cancellation of East-West and North-South. Below is the result after fourth and final iteration

[North (20), West (10), South (30), East (30), North (15), East (15), South (20)]

When we reach the above iteration and the shortest path does not reduce any further with the "cancellation of samples in opposite direction strategy", we will break the logic. Let us go through few important methods which I have used in the Cruiser class to come up with the shortest path. 

run(): This is the run() method of the Cruiser thread which has the important logic to find and follow the shortest path. It calls three main methods to complete our goal.

populateFirstPathSamples()
findShortedPath()
followShortestPath()

summarize(): While explaining this method I am assuming that you have gone through Limited Maze Solver article in detail. In addition to my explanation there, I want to mention that in this method we take into account all the consecutive direction changes. With each direction change, we keep a record of the number of samples in the same direction. Let us assume that while populating the First Path samples, we get the direction sequence as follows (as known from the direction property of the summary objects):
[4, 4, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1]
This sequence will get recorded into our directionOutput objects as follows:
4 (2), 2 (4), 3 (5), 1 (5)
Here, the figures in the bracket represent the number of samples in the given direction. Each directionOutput object has four properties like summary objects, X, Y, direction and removal. In addition to that I have introduced one more property, numberOfSamples.  

Plotted TachoPoseProvider Readings

I realized that the Maze Solver was going little ahead of the path that was expected. To look for a reason, we decided to visualize the way the robot traverses the path. We exported the data which the pose provider gathered, to the computer. And we plotted the way the path looks like. The above image represents the "actual path" that is visualized by the robot. At the end, the robot diverges from the path that it is expected to travel. 

findShortedPath(): Calls the methods removeOppositeDirections42, removeOppositeDirections24, removeOppositeDirections13, removeOppositeDirections31 and removeUTurn iteratively until the shortest path size cannot be further reduced. Let us take a look at removeOppositeDirections42 method in detail. We will also take a look at removeUTurn method in detail

removeOppositeDirections42() 
Follow entire shortest path and check whether the directions 4 and direction 2 appear consecutively. Check the corresponding number of samples with each direction as explained above. Then call the decideWhichOneToRemove() method by passing the entire shortest path and the index of direction 2. Extract the number of samples for both, the direction 2 and its previous direction 4 in the direction array. Find the difference between the samples of direction 2 and direction 4. If the difference is less than DIFFERENCE_BETWEEN_EQUAL_SAMPLES, treat the distance between the two directions 2 and 4 as equal and nullify them by removing both of them from the direction array. 

NOTE: I have created the constant DIFFERENCE_BETWEEN_EQUAL_SAMPLES = 11, because due to technical/processing lags, the difference between two equal and opposite directions, may not be exactly zero. So, I have created a threshold of 11 samples to consider the equal and opposite number of samples.    

If the difference between the samples of equal and opposite direction is greater than 11, that means there is unequal distance travelled in the directions. In such case, subtract the longer distance from the shorter distance and set the difference appropriately in either direction 2 or direction 4 (based on the direction which is travelled more)

removeUTurn(): 
Follow the entire path and check if any of the directions 1, 2, 3 and 4 has number of samples less than 11, we remove all those directions from the shortest path, considering either it is a U-Turn or it is noise.  

followShortestPath()The algorithm for following shortest path goes as follows:

  1. Extract the number of samples in the heading direction of the robot from the shortest path array
  2. Follow the path with PID controller pilot for the above number of samples   
  3. Get two more samples from the pilot
  4. Check if the direction property of those two samples match with the next direction in the shortest path array
  5. If the directions match, move the shortest path array pointer to the next direction and continue with step 1
  6. If the directions do not match, align the direction by calling the alignDirection() method, then move the shortest path array pointer to the next direction. Add the STABILIZATION_ SAMPLES to the number of samples in a given direction. Then continue with step 1
NOTE: I have added the STABILIZATION_SAMPLES in order to give the robot some time, to align in a given direction appropriately. However, from the performance of the robot, it looks like it is NOT required to add them. Because due to addition of them, the effect is little different. Whenever the robot is expected to the change the direction, considerable delay is present. Like the robot should turn much earlier before taking U-Turn number 1. However, it almost reaches till the end. This is because of accumulation of all previous stabilization_samples during direction changes. Same behavior is evident at U-Turn number 5. The robot is expected to stop immediately after taking the turn, however it goes ahead much further.   

alignDirection(): This method is used to turn and align the robot in different directions based on the required direction changes in the shortest path. I call the steer API of the robot which turns it onto a circular path. Please note that the entire turning will not be in the first stretch, because I have used angle 60, -60, -90 to turn. This method may need to be called twice to get the robot at the appropriate angle. For example: we need to call the pilot1.steer(-180, 60) twice to get a turn reach 90 degrees. We may need to call the pilot1.steer(-200, -90) twice to get a turn of 180 degrees. If we leave the robot at an intermediate angle, Line-Follower behavior will come to help, to automatically bring the robot on the black stripe from the white surface. 

NOTE: The performance of the robot is dependent on tuning the following properties appropriately:
  • STABILIZATION_SAMPLES
  • DIFFERENCE_BETWEEN_EQUAL_SAMPLES
  • U_TURN_SAMPLES
  • TOTAL_SAMPLES
The TOTAL_SAMPLES constant works in the first phase of robot traversal of the path. These are the samples required to complete the traversal across complete trajectory. This number is coined with a bit of trial and error and observations.

 

Saturday, 28 November 2015

Limited Maze Solver With DifferentialPilot and PIDController


Maze solver being a complex topic for me, I decided to start with a simplest maze first (check the video). The program is inspired by the video here. The main reference for finding the shortest path is here. The code for this program is given below. The program works with DifferentialPilot and PIDController classes supported by leJOS. The program works in two phases. In the first phase, it samples the entire path for the direction in which the robot is moving. It then applies the shortest path algorithm over the direction. In the second phase robot follows the shortest path. I will explain all the methods in the program below. 

Cruiser(): This is the Cruiser class constructor which internally calls pidInitialize(), pilotInitialize(), pid1Initialize(), pilot1Initialize(). 

run(): This is the method over the Cruiser thread which implements the shortest path following algorithm (from the left), by calling following methods in sequence:
  • populateFirstPathSamples()
  • findShortedPath()
  • followShortestPath()
populateFirstPathSamples(): It populates the summary array. This array contains the instantaneous values of X and Y coordinate of the robot's pose and also the Direction of the robot's pose while traversing the path for the first time. I have introduced a variable removal in order to use it for plotting the trajectory of the shortest path. This method executes the following steps in order to populate the summary array:
  • Call getASample(), which return the X and Y coordinates for the robot, based on its pose while collecting the sample
  • Populate X, Y, Direction and Removal properties for the sample in a Direction object and create a single entry in the summary array. Please note that the Direction object has a direction property too. 
  • Repeat the above steps for 180 times (The figure 180 samples collection, is coined through a bit of trial and error). You guessed it right, there will be 180 entries in the summary array at the end of the traversing the entire path for the first time. Each entry will be of type Direction object 
getASample(): Steers the entire path with the PID controller and samples the path after each 10 milli seconds. It does such sampling 10 times, gets the X and Y position at each sample. It averages X and Y over these 10 samples. It puts the X and Y values in the sample array. So, by this time you should know that each sample consists of only 2 elements, the X and Y coordinates of robot's pose (averaged over 10 samples). 

getDirection(): This method decides the direction in which the robot is moving as per the following figure. 


This method assigns the following numbers with the directions:
North = 1
East = 2
South = 3
West = 4

Below is the algorithm for setting up the direction variable
  • The input to this method is the X and Y coordinates of the current pose and its previous pose. 
  • dx is difference between the X coordinate of the current pose and X coordinate of previous pose
  • dy is the difference between Y coordinate of current pose and Y coordinate of previous pose
  • I have set direction of movement from South to North to be when the line passing through the two poses of the robot has a slope less than 1 and dx is greater than 0
  • I have set direction of movement from North to South to be when the line passing through the two poses of the robot has a slope less than 1 and dx is less than 0
  • I have set direction of movement from East to West to be when the line passing through the two poses of the robot has a slope greater than 1 and dy is greater than 0
  • I have set direction of movement from West to East to be when the line passing through the two poses of the robot has a slope greater than 1 and dy is less than 0
summarize(): This method executes the following crucial steps:
  • Out of 180 summary samples, remove all the summary samples where direction = 0. That means neither of East, West, North, South is associated with it
  • Out of the remaining summary samples, consider only those where consecutive samples does NOT have the same direction. That means I am considering only those consecutive summary elements with changes in the direction to be on the shortest path. 
findShortedPath(): As mentioned in the summarize() method above, the shortest path list takes all the summary samples which represent change in the direction, as an input. Then it removes all the samples where the previous three direction changes look like 4-1-2 in a sequence corresponding to West-North-East. This sequence represent the U turn (which is little delayed turn) which the robot takes at the dead end. I have come up with this sequence removal after observing the logs which I print in the program. 

followShortestPath(): As we know now, that the shortest path constitutes the changes in the direction of the robot. To follow the path, consider the following algorithm. 
  • Collect the first three samples from pilot1 for the second phase. 
  • Don't take any action until the three samples are aligned in the same direction as shortest path. Just keep following the path. 
  • The moment the direction of the three samples get misaligned, start taking a turn. Then stabilize until the stabilization count gets decremented to zero. 
  • After mis-aligning and consequent stabilization, if the three consecutive samples get aligned with the next index of the shortest path, increment the shortest path index to point to the next direction.
  • Then start with the next three samples of pilot1 and repeat the same procedure again!   
NOTE: The number three for three consecutive samples while following the shortest path is considered after some trial and error. We can even go for comparing two samples or four samples. However, two samples will make the algorithm more error prone. And four samples will create some delay in processing.  



Monday, 7 April 2014

Omni Biped

Below is the Java program for the Omni Biped robot (one creation from Daniele Benedettelli's book 'Creating Cool Mindstorm's NXT Robots'). The main design of the program is inspired by the author's Single Task 'C' program given in the book. The robot walks forward until it encounters an obstacle in front of it. As soon as it encounters an object, it takes a turn until there is no further obstacle on its way. 

Let me explain about the program a bit. The program has two classes, OmniBiped and NXTUtils. The OmniBiped program has the main method which begins with calling the init() method. The init() method resets the tachometer count and realigns the legs. In Lego Mindstorms NXT, units of measurements used are in tachometer counts rather than rotation or degrees. One pulse of tachometer is equal to one degree. To complete one full step, the robot requires 3 complete rotations of the motor. That means it requires 1080 tacho-counts (or 1080 degress). Whereas to complete half a step, the robot requires 540 tacho-counts (or 540 degrees). The realignLegs() method aligns the legs such that the initial position of the legs will be as shown in the following picture. As you should see, the 



After the initial position, the feet take half step which look like below. 



After half a step, the feet take full step which look like below. 




While realigning, the program calculates the right_count and the left_count. These counts represent the number of degrees each leg require to complete a full step, in case the robot stops in an intermediate position of legs. If this count is less than half a step distance, the robot prefers to take the respective leg backwards (because that is much quicker to achieve the realignment). In case if this count is more than half a step distance, the robot prefers to take the respective leg forward. While moving the motors forward or backwards, the tachometer count gets updated. When the right_count as well as the left_count become less than zero, the motor stops that means the re-alignment process stops. 
 
Now let us come back to the main() method. It calls the init() method and realigns the legs. Then the robot begins walking, with both the legs moving forward. That means, the motors moving the respective legs are driving forward. They keep driving forward, until an obstacle occurs at less than 24 cm distance (as defined by the constant NEAR). Once, the obstacle occurs on its way, both the motors stop, the legs are realigned again and the robot moves either left or right randomly based on the direction variable. The direction variable can be either -1 or 0 or +1 (representative of left/right direction). The robot can move in any one of these two directions until there is no obstacle within the range of 50 cm (as defined by the constant FAR). 

The robot measures the distance to the obstacle by the getAvgUltrasonicSensorReading() method in the NXTUtils class. This method averages the distance to the obstacle over 5 samples. I calculated the average in order to smoothen out the spikes in the ultrasonic sensor readings. 

Below is a small clip showing the behavior of the robot. 

  


NOTE: Please look at the commented part of the code carefully and do not consider it. 

If we analyze the movement of robot, it moves straight quite well in the beginning. It also stops when it encounters an object at less than 24 cm. Once the object encounters the robot takes a turn quite well. However the robot appears quite stuck when it approaches the cable and the wall at an angle (not exactly in front of it). When object approaches at an angle, the robot has to take multiple turning movements, which appears quite slow.  

I hope you liked this article!

Reference Sites:

Friday, 9 November 2012

Line Follower

Here is a small clip showing the Line Follower performance and the LeJOS code associated with it. The robot here is the small car which is built using small booklet provided with NXT kit. The LeJOS firmware for NXT can be downloaded and installed on the NXT brick from LeJOS NXJ 0.9.1. The design of my Java program is heavily influenced by the Line Follower in the book "Programming Lego Mindstorms with Java" by Giulio Ferrai et all. The actual algorithm to follow the line is influenced by Jacek Fedorynski's Line Follower NXC program. The LeJOS program has four classes: LFJfedor, Cruiser, LFUtils and LineValueHolder. The LFJfedor class contains the main method and is the starting point of the program. This class initializes the light sensor and calibrates the sensor for Black and White values in its constructor. The black and white values are stored inside a Java Bean called LineValueHolder. LFJfedor class also starts the thread Cruiser.  The Cruiser class has the algorithm to follow the line, given the calibrated black and white values and the light intensity at any given point in time. LFUtils class calculates the average light intensity over 20 samples, at any given point of time. The average over 20 points is calculated in order to smoothen out the spikes in the light intensity (if they exist). Let me explain some of the program details below.  

In order to calibrate the threshold for White, the NXT brick beeps twice. It prints the message "white" on the screen of the NXT brick. The user is supposed to keep the light sensor on the White part of the line follower chart and press the ESCAPE button. This process will record the White light intensity in the Java Bean  LineValueHolder. Similarly, record the Black value when the NXT beeps twice again. It prints the message "black" on the NXT screen. The user is supposed to keep the light sensor on the black strip of the line follower chart and press the ESCAPE button. This process will record the Black light intensity in the Java Bean LineValueHolder. Once the White and Black intensities are recorded, the Line Follower program works as follows:

  1. The Line follower follows the edge of the line where the threshold value is (Black + White)/2
  2. The instantaneous value of the light is calculated by averaging over 20 light samples
  3. The B Moter and C Moter is powered in proportion to the difference between the threshold and the instantaneous value of light (defined by the variable "color")
  4.  The initial value of power = 22 and the constant multiplier 50 requires few attempts to be set correctly in order to follow the line, in a certain speed







I wish you enjoyed the article!

Tuesday, 14 August 2012

Maximize Sound

This is a small program which I have come up with, to learn about sound sensor and data wiring in NXT. Here the robot's "roaming boundary" is decided by decreasing sound level. That means, the robot tries to remain within the boundary where raw sound level drops by 100. The robot should move away from the sound source only until the sound level drops by 100. After which the robot is supposed to take a U turn and move more closer to the sound source. Let's go through the NXT-G program to achieve this goal. Please click on the below image in order to maximize it and take a look at the NXT-G program. Alternatively, you can also download the .rbt file and check out the comments to understand the NXT program.



Let me explain all the blocks to you one by one.

  1. Drag and drop the Sound Sensor block on the sequence beam in the Work Area
  2. Drag and drop the Variable block and put it next to the Sound Sensor block. Name this variable as maxsound
  3. Stretch a yellow wire from the Sound Sensor Block to the input of the Variable block. This will initialize the maxsound variable with the sound sensor sample
  4. Drag and drop the Motor Block on to the sequence beam and configure it using the configuration panel to move the motors B and C for two seconds
  5. Drag and Drop the sound sensor block to collect the sound sample (after forward movement of the robot in step 4)
  6. Drag and drop the Variable block and put it next to the sound sensor block. Name this variable as sound
  7. Stretch a yellow wire from the Sound Sensor Block to the input of the Variable block. This will initialize the sound variable with the sound sensor sample
  8. Drag and drop the variable block maxsound on the sequence beam, and put it next to all the previous blocks
  9. Drag and drop the variable block sound on the sequence beam, and put it next to all the previous blocks
  10. Drag and drop the Compare block and put it next to all the previous blocks
  11. Stretch yellow wires from maxsound and sound variable blocks and make them as inputs to the Compare block
  12. Drag and drop a Switch block and place it on to the sequence beam
  13. Draw a data wire from the output of the Compare block to the input of the Switch block. If sound is greater than maxsound, the upper part of Switch block will be executed. If the sound is lesser than maxsound, the lower part of the Switch block will be executed
  14. If sound is greater than maxsound, copy the value of sound variable in maxsound variable. That will keep maxsound variable updated with the maximum value of sound so far. Do this by dragging and dropping the sound and maxsound variables on to the upper part of the switch and stretching a wire from sound output to maxsound input 
  15. Next, find the difference between the peak sound reading and the latest sound reading. Check if the difference between the two sound levels is greater than 100. We can achieve this by dragging and dropping the sound and maxsound blocks on the sequence beam and putting the Maths block next to them. Stretch the yellow wires from the sound and maxsound variables to the Maths block input. Then stretch a yellow wire from the output of the Maths block to the Compare block to check if the difference between sound and maxsound is greater than 100
  16. Drag and drop a Switch block and place it on to the sequence beam. The Switch block has two parts, upper and lower. The upper part gets executed if the input is True. And the lower part gets executed if the input is False. Drag a wire from the output of the Compare block to the input of the Switch block. If the output of the Compare block is true (if the difference between sound and maxsound is greater than 100), the robot will take a U turn. This can be achieved by placing a Motor Block in the upper part of the Switch with only a single Motor on. In my case its a C motor 
  17. Place the steps from 4 to 16 in a loop which will execute them again and again forever.


In Essence the entire algorithm of bringing back the robot after reaching a point where sound level drops by 100 is as below:

  1. Keep the maxsound variable updated with maximum sound value so far
  2. Keep comparing the maxsound with the latest sound sample (The latest sound sample will keep reducing as and when the robot moves away from the sound source)
  3. If the difference between the maxsound and latest sound sample is greater than 100, make the robot take a U turn
  4. If not, keep the robot moving forward

Please take a look at the functioning of the robot in the below video clip. 




Hope you enjoyed the article!

Please go through the below article to know about Lego data wiring in detail.

Tuesday, 31 July 2012

Move Forward Until Occurrence Of Black Boundary

Now, let's give the robot a restricted space to move. The robot here is the small car which we can build by following the small booklet provided with the NXT kit. Let us draw a black line around the robot's space, to identify its boundary. When the robot touches the black line, it is supposed to take reverse and try another time to escape the boundary. The question is how the robot notices the black boundary? Yes, we have to use a Light Sensor. Light Sensor measures the light intensity in a room and converts it into meaningful values. It passes the values to the NXT. NXT can then use a calibration program to convert the light sensor values into minimum and maximum. Calibration process allows the sensor to get the readings within an acceptable range which then makes programming easier. Please take a look at below video to see the different ways provided by NXT to calibrate the light sensor. You can go ahead with any one way and calibrate your sensor. 


Let's start to write a program which then uses the calibrated values to understand robot's boundary. It is going to be a two-step program. 
  • Keep moving forward until the robot hits a black boundary line (Light Sensor helps to identify the black boundary line)
  • When robot hits the black boundary line, drive backwards for 2 seconds
Keep repeating the above steps and observe robot’s behavior. Now let's program these steps with the help of NXT-G programming language. Drag and Drop the Switch Block from the left Palette to the Work Area. This Switch has two parts, the upper part and the lower part. The upper part controls the unusual behavior of the robot. The lower part controls the default behavior of the robot. Now, click on the Switch and see its configuration panel at the bottom of the screen. Please select the below configuration fields and their values.

Control - Sensor
Sensor - Light Sensor
Port - The port number where light sensor is connected (in my case port 3)
Light - Greater than 20 (which means when the light intensity exceeds 20% of the maximum value)

This configuration means that the light sensor will consider darkness when the illumination is about 20% of maximum and it will consider brightness when the illumination exceeds 20% of maximum. Please take a look at the below figure to see my configuration of Switch Block. 


As a next step, let us drag and drop a Motor Block in the upper part of the Switch. This Motor Block will get activated when the robot finds brightness. Click on the Motor Block and see its configuration panel at the bottom of the screen. I would like the robot to keep moving forward until it is in brightness. I selected the motors B and C in order for robot to move forward for unlimited duration. Keep rest all the configuration the same. Please see the below configuration of my Motor Block on detection of light. 


Next, let us drag and drop another Motor Block in the lower part of the Switch. This motor block will get activated when the robot encounters the black line. Click on this Motor Block and see its configuration panel at the bottom of the screen. Since I would like the motor to go reverse for 2 seconds on occurrence of the black boundary, I have selected Motor B and C of the robot, with Direction field to be reverse and Duration to be 2 seconds. I kept rest all the fields to be default. Please take a look at the figure below to check my configuration of the Motor Block. 



Further, configure the robot to keep moving between light and dark indefinitely. In order to achieve this please put the entire configuration above in a Loop. Click on this loop and see its configuration at the bottom of the screen below. Please select the Control field to be Forever. Please see my final NXT-G program below. 
 


Download this program on the NXT brick and see the movement of the robot. The below video clip captures the movement of my robot. 



As seen in the video, the light sensor is mounted on the front part of the robot, about 2 mm above from the surface and has a red light emitted out of it. The robot touches the black boundary line twice and then reverses back for 2 seconds. 

For learning about Lego NXT blocks please visit the site below. 

Hope you enjoyed the article!

 

Monday, 23 July 2012

Roaming With Ultrasonic Sensor

In the last post, we used the touch sensor to detect an object. However, touch sensor responds on colliding with an object. Colliding could harm our robot (The robot here is the small car which we can build by following the small booklet provided with the NXT kit). So, let's use an ultrasonic sensor. Ultrasonic sensor detects an object when it is at a certain distance from the object. Thus ultrasonic sensor gives a much cleaner object detection. The robot follows the following rules while moving around in the world. 
  • If there is no object in 50 Inches distance in front of the robot, the robot keeps moving on 
  • Once an object is detected the robot takes following two steps
    • Get the robot reversed for 2 seconds
    • Turn the robot away from the obstacle by turning the motor 180 degrees
Now, let's take a look into the NXT program to achieve the above behavior.

At first, drag and drop the Switch Block from the left palette to the work area. The Switch Block has two parts. Upper and Lower part. The upper part gets enabled when the object is detected within 50 Inches limit. The lower part gets enabled as a default function of the robot. Click on the Switch and you will get to see its Configuration Panel at the bottom. In the Configuration Panel, please select Control field to be Sensor. Further, choose Sensor field as Ultrasonic Sensor. Select the port where Ultrasonic Sensor is attached to the NXT brick. In my case it was Port-4. Select the Compare field to be of Distance less than 50 (it is a little mathematical expression) and its unit to be Inches. That means the ultrasonic sensor will detect an object if it is in the range less than 50 Inches. Please take a look at my configuration in the below figure. 





Now let us program the first step on object detection. The car gets reversed for two seconds. In order to achieve that please drag and drop the Motor Box on to the Work Area within the upper part of the Switch. Click on this Motor Box. The Configuration Panel of the Motor Box will appear at the bottom of the screen as shown in the figure below. I am using Motor B and Motor C to drive the car. So I have selected the motor options accordingly. Since I want to drive the motors reverse, I have chosen the Direction option to be reverse arrow. Choose the Duration to be 2 seconds. Keep rest all the options as default. 



Let's program the second step of object detection, which is to take a turn to move away from the object. To do this, please drag and drop the Motor Box from the left Configuration Palette to the Work Area, just next to the previous Motor Box. This will make the previous and the current actions execute sequentially. Click on this Motor Box to get its corresponding configuration at the bottom of the screen. As shown in the below figure, this box is configured to take a turn to move away from the obstacle. To take a turn (in place), enable a single motor, in my case Motor B. Please select the Duration option to be 180 degrees. That means the servo motors of the robot will be programmed to take a 180 degrees turn. Please remember, the servo motor turn is very different from the 180 degrees turn in the physical space. To know more about Lego NXT Servo Motor design, please visit 




Now configure the Motor Box to take a default action of moving forward, when there is no object in the limit of 50 Inches in front of the car.  Place this Motor Box in the lower part of the Switch box as shown in the below figure. Click on the Motor Box to get its configuration at the bottom of the screen. Since we want to keep the motor freely moving forward in the default condition, we will select the Motor B and Motor C with the Direction to be Forward Arrow. The Duration is selected to be Unlimited and rest all the configurations are kept as unchanged. 



As the last step, we need to put the Switch Box in a Loop, which will allow us to run all the configurations inside the loop forever. Please drag and drop the Loop from the left palette and place it around the Switch Box. Click on the Loop to see its configuration at the bottom of the screen. Please select Control field to be Forever. See the figure below for my configurations. 



Further, we will download our program on the Lego NXT brick and see the results as shown in the below video. 





You can see that every time when the obstacle is encountered, the robot goes reverse for 2 seconds and then take a turn of 180 degrees in Motor Space. In my case, at first the car encounters my hand in front of the ultrasonic sensor, so the car goes back when I switch the Lego NXT Program ON. Then the car encounters the wall. The robot can not turn away from the wall in one go. So you will see that there are multiple "reverse and turn" actions to move away from the wall. At the end, the robot encounters a soft toy. For some reason the Ultrasonic Sensor is unable to detect the fabric of the toy. May be, because the robot approaches the toy from a different angle or because the ultrasonic sensor is unable to detect the fabric itself. 

I hope you enjoyed this article!

Thursday, 19 July 2012

Roaming With Touch Sensor

Now, let's take it a little further and set the car robot free to roam around. The car in this article is built using the small booklet which is delivered with the Lego kit. Now think, what if the robot collided with an obstacle! There comes the role of a touch sensor. Touch sensor gives the robot a sense of obstacle on its path. The sensor communicates this information to the NXT. NXT then decides what action to take, if an obstacle is present. So, lets take a look into the NXT program to observe the robot's behavior in the free world! In this project, the robot handles two distinct situations. 
  • If there is an obstacle present on the path, (as realized when Touch Sensor is pressed), do the following
    1. Make the robot go reverse
    2. Take a turn to move away from the obstacle
  • There is no obstacle, (as realized when Touch Sensor is in released or bumped state)
    1. Keep the robot moving forward
Let's program for the above two situations now. Drag and drop the Switch block from the left palette. This block performs certain actions when specific conditions are met. You will observe that there are two parts of the Switch box, the upper and lower one. 



Click on the Switch Box to see its configuration panel at the bottom of the screen (Please check the above figure). As per the configuration, please make sure that the sensor is selected to be Touch Sensor and the sensor is connected to port number 1 of NXT brick. The action is selected to be pressed. That means we have configured the upper part of Switch box if touch sensor is in pressed condition and below part of the Switch box is configured for sensor to be in other conditions, which are released or bumped. Drag and Drop the Motor Box from the left palette, over to the upper part of the Switch Box. Click on the Motor Box to see its configuration panel at the bottom of the screen. Configure this panel to make the car go reverse, when the obstacle is found and Touch Sensor is pressed. Please power on the motors B and C to go into reverse direction for 2 seconds. Keep rest of the configuration as it is. The below figure shows the configuration panel for the motor box for my car.     

 


Drag and drop another Motor Box in the upper part of the Switch Box, and place it next to the previous Motor Box (which we used for reversing the car). Click on this box and see its configuration panel at the bottom. Configure this Motor Box to take a turn. In order to take a turn, powered on only one motor (in my case Motor B) in reverse direction for 1 second. This will make the car move away from the direction of the obstacle. Please check the below figure for the configuration of this second Motor Box.   



Now drag and drop the third Motor Box in the lower part of the Switch Box, which will function in all other states of the touch sensor except pressed state, for example Bumped and Release state. This box will keep the car moving forward in the default conditions. Please check the figure below. 



Click on this third Motor Box and check its configuration panel below. I have configured it for my car to power on the Motors B and C to move in forward direction for unlimited duration. Now is the time to put the entire switch in a loop which will help the car to execute all previously defined steps forever. Please check the figure below. Click on the loop and we get the Configuration Panel of the loop at the bottom. Please select forever, in order to keep the car moving for its entire lifecycle. 




Download the program on to NXT brick and observe the movement of the robot. I have recorded the movement of my robot in a small clip below. 



As you can view from the clip, the robot encounters three obstacles on its way. On every occurrence of obstacle, the robot reverses, then it makes a turn and then start moving forward. Hope you enjoyed this article!



Sunday, 15 July 2012

Return To Origin

Let's move on and make the robot move little more distant. The robot here is the small car which is built using small booklet provided with NXT kit. Let's make it a point that the robot will come back from where it has started. So, I have made the robot move for 5 seconds, make it take a U-turn and return to its origin. Let's take a look at the steps that we are going to follow. 


I will program the three steps mentioned above using NXT-G programming. Let's program for the first step Go Forward.


As shown in the figure above, drag and drop the Motor Block from the left palette to the Work Area. Click on the Motor Block and check its Configuration Panel in the bottom. Since we want to program it to move forward, we need to move both the rear wheels with the same speed for the same time. In my case, the rear wheels were powered on by Motor B and Motor C. So I have checked the ports B and C in the Configuration Panel. I want to drive the motor for 5 seconds, so I have specified the Duration to be 5 seconds. Next step for the robot is to take a U-turn (either from the left or from the right side). In order to do this, please drag and drop the Motor Block to the Work Area in succession with the first block shown in the above figure. The NXT-G program now looks like below. 


Please click on the second Motor Block and check its configuration at the bottom. In order to take a U turn, stop one of the rear motors and power-on the other motor. In my case I am powering on the C Motor and stopping the B motor. That will make the robot take a turn. To take a complete U-Turn the motor has to be rorated through 810 degrees (We came up to this number through multiple trial-and-error). Keep rest of the configurations as they are. And let's move to configuration of the third step, which is Come Back to The Origin. The NXT-G program now looks like below. 


  
As you can see the program now has three Motor Blocks in succession which correspond to the three steps which are required to return back to the origin. In order to configure the third Motor Block, click on to the block and check its Configuration Panel at the bottom. I have powered on both the rear motors for 5 seconds of duration as shown in the above figure. Now it's the time to run the NXT-G program and see the output in the below video. I have used the Line-Follower paper just as a baseline in order to get the correct start and end point of the robot. 


Friday, 13 July 2012

Spinning Motion


Recently I have started understanding Lego Mindstorms NXT programming. As and when I update my learnings, I thought of sharing it with you. Please find a small program below in NXT-G, to spin the Robot in a clockwise direction. 



The robot here is the small car which is built using small booklet provided with NXT kit. In order to begin programming, drag and drop the Motor Block from the left palette to the Work Area. Click on the Motor Block on the Work Area and check its Configuration Panel in the bottom. Pick the appropriate port from the bottom Configuration Panel which is used to stop the right motor and power on the left motor. In my case the Motor Port to power on the left motor was Port C. Specify the Duration for which the motor needs to spin. I am spinning it for 5 seconds. Keep rest all the configurations as default. Please view the below video to check the output of the program.