Ping)))Dar - a Radar Style Display
Andy Lindsay (Parallax)
Posts: 1,919
Ping)))Dar – A Radar Style Display·
This activity features a program that displays what the Boe-Bot detects in the Debug Terminal as it sweeps the Ping))) rangefinder back and forth. Figure 1 shows an example with a cup and box set in the Boe-Bot's 180° field of detection along with their signatures displayed in the Debug Terminal. Experimenting with this program will help you better understand what the Boe-Bot can and cannot detect with the Ping))) Ultrasonic Rangefinder and Mounting Bracket, which is important for writing programs that navigate with this object detection system.
View Video Introduction – (YouTube)
Download Source Code – Ping)))Dar
Figure 2 shows a Boe-Bot assembled with the Ping))) Ultrasonic Rangefinder and Mounting Bracket kits. The mounting bracket kit makes it possible for the Boe-Bot to swivel the Ping))) rangefinder and measure object distances across a 180° field in front of it.
Figure 1: Seeing what the Boe-Bot Detects with Ping)))Dar.bs2
Figure 2: Boe-Bot with Ping))) Ultrasonic Rangefinder and Mounting Bracket Kit
·
Getting Started
This project contains advanced topics, not intended for Boe-Bot beginners. ·Before continuing, it is highly recommended you complete the following tasks in order to gain a better understanding on how this program operates:
√······· Complete all activities in What’s a Microcontroller
√······· Complete at minimum Chapters 1-4 in Robotics with the Boe-Bot
√······· Complete at minimum Chapters 1-3 in Smart Sensors and Applications
√······· Download the product documentation and assembly instructions for the PING))) Bracket Kit
Parts Required
(1) Fully assembled and tested Boe-Bot® Robot
(1) Ping))) Ultrasonic Rangefinder
(1) Ping))) Mounting Bracket Kit
Polar to Cartesian Coordinate Conversion
Ping)))Dar.bs2 will scan a 180° field in front of the Boe-Bot by incrementally rotating the Ping))) Mounting Bracket and then taking a distance measurement. It will do this rapidly enough that the mounting bracket servo will appear to just be rotating from right to left and back again as it updates the Debug Terminal display.
·
For each measurement in a given sweep, the information Ping)))Dar.bs2 will have to work with is a distance measurement (d) and an angle measurement (θ[noparse];)[/noparse] as shown in Figure 3. When coordinates are given in terms of distance and angle, they are called polar coordinates. These coordinates are typically expressed in parentheses like this: (d θ[noparse];)[/noparse]. When telling those coordinates to someone, you would normally say, "d at an angle of theta." In order to display these measurements graphically in the Debug Terminal, Ping)))Dar.bs2 will have to convert these polar coordinates to Cartesian (x, y) coordinates. That way, the DEBUG CRSRXY, x, y, "*" command can be used to graphically display the measurement by positioning the cursor and then placing an asterisk.
·
Figure 3: Object's Polar and Cartesian Coordinates
·······
Calculating the x and y axis components given polar coordinates is not difficult. The equations for x and y are shown below. The x-axis component involves multiplying the distance by the cosine of the angle, and the y component is the distance multiplied by the sine of the angle.
·
Since the BASIC Stamp is an integer math processor, the programming for making these conversions is a little different from what you might expect with a PC programming language. Ping)))Dar.bs2's Polar_To_Cartesian subroutine is explained in Advanced Topic − Inside the Polar_To_Cartesian Subroutine.
Assembly and Electrical Connections
√······· Follow the instructions in the Ping))) Mounting Bracket Documentation for making the mechanical and electrical connections to the servo and Ping))) Ultrasonic rangefinder. When you are done, the servo will be connected to the Board of Education's servo port 14, and the Ping))) rangefinder will be connected to port 15.
Mounting Bracket Adjustments
Keep in mind that Ping)))Dar.bs2 will measure distances and angles. Recall from What's a Microcontroller that a PULSOUT command's Duration argument sends a message to a standard servo telling it what rotational position to hold. In other words, the PULSOUT command's Duration argument tells the Ping))) mounting bracket's standard servo what angle to turn to.· Ping)))Dar.bs2 will need to convert the PULSOUT command's Duration argument to a binary radian measurement before the program can do polar to Cartesian coordinate conversion. Since the object's position is dependent on good distance and angle measurements, it will be important mechanically adjust and calibrate your Ping))) Mounting Bracket system so that the program's PULSOUT commands can sweep it from 0° (to the right) to 180° (to the left).· The first adjustment step toward good Ping))) Mounting Bracket servo angular control is making sure that the Ping))) rangefinder is mounted so that the servo points the Ping))) rangefinder straight ahead when the servo receives 1.5 ms center pulses.
·
√······· Run PingServoCenter.bs2.
√······· Make sure the Board of Education's 3-position power switch is set to position-2.
√······· Check to see whether the mounting bracket servo points the Ping))) rangefinder straight ahead on the Boe-Bot.
√······· If it does, then continue to the Software Calibration for 180° Sweep section.· Otherwise, keep following the checklist instructions here.
√······· Make sure CenterPing.bs2 is running for the remaining checklist instructions in this section.
√······· Start by removing the screw that connects the servo horn to the output shaft shown in Figure 4 (a).
√······· Pull upward on the Ping))) rangefinder. The horn, which is attached to the Ping))) rangefinder with screws should slide up and off the servo's output shaft, also shown in Figure 4 (a).
√······· Orient the Ping))) rangefinder so that it is pointing straight ahead as shown in Figure 4 (b).
√······· Slide the servo horn back onto the output shaft.
·
·
√······· Screw the screw back in that holds the servo horn to the Ping))) mounting bracket.
·Figure 4: Mounting the Ping))) Rangefinder so that It Points Straight Ahead
·······
√······· To adjust for any slight error caused by the output shaft to servo horn gear teeth alignment, start by loosening the screws that attach the servo to the Boe-Bot chassis.
√······· Now, you will have some wiggle room to rotate the servo's housing slightly to make up for any offset resulting from the alignment of the servo horn and output shaft's teeth.
√······· Make sure to re-tighten all the screws when you are done.
Example Program – PingServoCenter.bs2
Software Calibration for 180° Sweep
The Boe-Bot needs to be able to point the Ping))) rangefinder from 0° (to the right) to 180° (to the left) as shown in Figure 5. The Ping))) mounting bracket's servo should direct the ping to 0° when it receives 0.5 ms pulses and to 180° when it receives 2.5 ms pulses. Since the PULSOUT command times pulse durations in terms of 2 μs units, the command PULSOUT 14, 250 will cause the servo to rotate the Ping))) rangefinder to 0°, and PULSOUT 14, 1250 will direct it to 180°.
Figure 5: Angle and Ping))) Rangefinder Direction
·······
The TestPingDirection.bs2 program declares LimitRight and LimitLeft as constants equal to 250 and 1250. The program also declares PingServo to be PIN 14 and Center to be 750. So the command PULSOUT PingServo, LimitRight should direct the rangefinder 0° to the right, and PULSOUT PingServo, LimitLeft direct the rangefinder 180°. Also, PULSOUT PingServo, Center should point the rangefinder straight ahead.
·
If the LimitLeft and LimitRight constants do not make the servo point the Ping))) rangefinder to 0° and 180°, the program's CON directive values should be adjusted. For LimitRight, values smaller than 250 will cause the servo to rotate further in the clockwise direction (to the right) while values larger than 250 will cause it to rotate to a position closer to center. Likewise, values greater than 1250 will cause the servo to rotate further in the counterclockwise direction (to the left) while values smaller that 1250 will cause it to rotate to a position closer to center.
·
√······· Run TestPingDirection.bs2 and make sure the servo points the Ping))) rangefinder to 0°, then to 180°, then to 90° (straight ahead).
√······· If the servo doesn't point to 0°, adjust the LimitRight constant accordingly.· Values less than 250 will result in more clockwise rotation and values greater than 250 will result in less clockwise rotation.
√······· If the servo doesn't point to 180° to the left, adjust the LimitLeft constant accordingly. Values greater than 1250 will result in more counterclockwise rotation, and values less than 1250 will result in less counterclockwise rotation.
√······· Update these CON directives, and make notes of the values you used. These same CON directives will have to be updated in this activity's Ping)))Dar.bs2 program and also in the next activity's GotoClosestObject.bs2 program.
Example Program – TestPingDirection.bs2
Testing Ping)))Dar
One of the most important things about Ping)))Dar.bs2 is that it will help give you a better idea of what the Boe-Bot "sees" as it sweeps the Ping))) rangefinder from left to right. Make sure to test a variety of objects at a variety of distances. Keep in mind also that the program is imposing a 100 cm distance limit on measurements to make the display more convenient.
·
Before running the program, the LimitRight and LimitLeft CON directives should be updated so that the servo that directs the Ping))) rangefinder to sweep from 0° to 180° using the values you determined with TestPingDirection.bs2.
·
Ping)))Dar converts the PULSOUT command's Duration arguments into binary radian servo rotation angle measurements with the help of a constant and the ** operator. Let's assume that LimitRight is 250 and LimitLeft is 1250. The main routine in Ping)))Dar.bs2 has code that sweeps the PULSOUT command's Duration argument from 250 to 1250 in increments of 15. As shown in Figure 6, that's about 2.7° for each increment of 15, which is pretty close to 2 brads (2.8125°).
·
Figure 6: Rotation Angle vs. PULSOUT Duration[/font][/size]
Mapping the PULSOUT command's duration argument to the number of brads the servo has rotated involves the ** operator. In the next example program, the command that does the job is angle = pingDir - LimitRight ** PingDirToAngle. The pingDir variable is used in the command PULSOUT PingServo, PingDir to point the Ping))) rangefinder to 0 brads (0°), then 2 brads, then 4 brads and so on all the way to 128 brads (180°). As it does this, the pingDir variable starts at LimitRight (250), then 265, then 280, and so on up through LimitLeft (1250).
Since the expression angle = pingDir - LimitRight ** PingDirToAngle subtracts LimitRight from pingDir before the ** operation, the value ** scales will range from 0 through 1000 instead of 250 to 1250. The PingDirToAngle constant has to be the right number of 65536ths to scale this range of 0 to 1000 into 0 through 128 brads. This is another job for the ** scale constant equation introduced in Chapter 3, Activity #3 in Smart Sensors and Applications
········
Here is an example of calculating PingDirToAngle constant when LimitRight is 250 and LimitLeft is 1250. Make sure to follow along because you will need to recalculate this constant based on the LimitLeft and LimitRight constants you determined for your mounting bracket system with TestPingDirection.bs2.· The number of output scale elements is 0 through 128, which is 129 elements since the range includes zero. Next, LimitLeft − LimitRight = 1250 − 250 = 1000. Again, we are talking about a range that's inclusive of 0, so there are really 1001 elements in the input scale.
·······
Substituting 129 and 1001 into the ** scale constant equation yields:
·······
Example Program – Ping)))Dar.bs2
Some of the checklist instructions below involve updating CON directives that you determined with TestPingDirection.bs2. While they are not necessarily crucial to this program, they will be crucial for GotoClosestObject.bs2, the Boe-Bot Ping))) Mounting Bracket navigation program in the next activity.
·
√······· Open Ping)))Dar.bs2 with your BASIC Stamp Editor.
√······· Update the LimitRight and LimitLeft CON directives in the program to tune the 0° right and 180° left pulse widths.
√······· If you changed either LimitLeft or LimitRight, calculate the value needed for the PingDirToAngle CON directive with the PingDirToAngle equation just discussed. Make sure to update this value in your program too.
√······· Make notes of all these CON directives because you will need to substitute them into the next activity's GotoClosestObject.bs2 example program.
√······· Run the program and maximize your Debug Terminal so that it takes up the entire computer screen.
√······· Observe the Debug Terminal as you try placing a variety of objects at various distances from the Boe-Bot at various locations in its 180° field of detection.
√······· Make sure to try the suggestions in the section after the example program entitled Your Turn - Understanding what the Boe-Bot Does and Does not "See".· It brings to light some of this setup's capabilities and drawbacks, and they turn out to be important for writing navigation programs.
Your Turn - Understanding what the Boe-Bot does and does not "See"
To understand what your Boe-Bot does and does not "see" with the Ping))) rangefinder, a few experiments are in order. Here are some questions that can be answered with Ping)))Dar.bs2 and various objects placed in the Boe-Bot's field of detection.
·
√······· If you place one object behind another object, can it see the object in back?
√······· How far do you have to rotate a flat object before it is no longer visible to Ping)))?
√······· Start with one or two cylindrical objects about 3 ft (91 cm) apart and 2 ft (61 cm) from the front of the Boe-Bot.
√······· As you move the objects closer to each other, how close can they be to each other before they appear to be one object in the Debug Terminal?
√······· If you keep the objects the same distance from each other but move them closer to the front of the Boe-Bot, is the gap between them detected again at some point?
√······· To what extent does setting the Increment constant is set to a smaller value help the Boe-Bot detect the gap between objects?
How Ping)))Dar.bs2 Works
The initialization routine applies forty pulses to make sure the servo turns and starts 0° (far-right). In this program, the FOR...NEXT loop is only used once. In GoToClosestObject.bs2 in the next activity, the loop is used frequently to point the Ping))) rangefinder in various directions, so in that program, the loop is placed in a subroutine called Point_At_PingDir. One other initialization detail is setting the sweepInc variable equal to the Increment constant (15). This value is used by the Sweep_Increment subroutine to rotate the Ping))) Mounting Bracket servo slightly between each distance measurement.
·
pingDir = LimitRight ··················· ' Start servo at 0-degrees
·
FOR counter = 1 TO 40 ·················· ' Initialize servo position
· PULSOUT PingServo, pingDir
· PAUSE 20
NEXT
·
sweepInc = Increment ··················· ' Set the sweep increment
·
The main routine's DO...LOOP refreshes the Debug Terminal display after each right-left sweep. As the main routine's DO...LOOP repeats, the first thing the program does is clear the Debug Terminal and place the "X" character at 50 spaces over and 25 carriage returns down. This "X" indicates the Boe-Bot's position.
·
IF pingDir <= LimitRight THEN ·········· ' Refresh display if far right
· DEBUG CLS, CRSRXY, 50, 25, "X"
ENDIF
·
Next, the program calls the Sweep_Increment subroutine, which adjusts the Ping))) Mounting Bracket's servo slightly each time it gets called. Calling this subroutine repeatedly each time through the main routine's DO...LOOP results in the back and forth sweeping motion. This subroutine uses the pingDir variable to direct the servo.
GOSUB Sweep_Increment ·················· ' Move servo by sweepInc
·
The Sweep_Increment subroutine modified the value of pingDir, and then used it in a PULSOUT command's Duration argument to point the Ping))) Mounting Bracket servo in a new direction. That means we can use the value of pingDir to determine the angle to which the Ping))) rangefinder is pointing in terms of binary radians.
·
Figure 7 shows a few examples of how the PULSOUT command's Duration argument relates to the Ping))) Mounting Bracket servo's rotational position. For example, when pingDir is LimitRight, (250), the angle is 0°, which is 0 binary radians (brads). When pingDir is 500, the angle is about 45°, or 32 brads. Likewise, pingDir can be 750 or1000, and the respective servo angles will be 90° (64 brads) and 135° (96 brads). By the time pingDir gets to LimitLeft (1250), the angle will be 180° = 128 brads.
Figure 7: PULSOUT Duration Argument vs. Rotation Angle
·······
Here is the command that converts pingDir, which ranges from LimitRight to LimitLeft (250 to 1250) to angle, which ranges from 0 to 128 brads. Note that this is the same kind of equation we used in Chapter 3, Activity #3 and #4.
·
' Calculate angle from far right in brads.
angle = pingDir - LimitRight ** PingDirToAngle
·
Without parentheses, PBASIC executes operators from left to right. So the command angle = pingDir - LimitRight ** PingDirToAngle first subtracts LimitRight from pingDir. This resulting value, which could be anywhere from 0 through 1000, has the ** PingDirToAngle operation performed on it. Since PingDirToAgle is 8454 in the example program, it means a value from 0 through 1000 gets multiplied by 8454 / 65536.· If pingDir stores 1000, the result is 128.9978, and the ** operator rounds it down to 128, which is the correct number of brads assuming the servo is in fact pointing left (180° from far right).· Likewise, (750 - 250) × 8454 / 65536 results is 64.4989, which rounds down to 64 brads, which is 90°, and the servo should be pointing straight ahead.
·
Next, the distance of the object at the angle the Ping))) Mounting Bracket servo is pointing to gets measured and scaled to a centimeter measurement. This centimeter measurement is further scaled down by 1/4 of its actual value to make it fit more conveniently in a Debug Terminal maximized in a typical 1024 by 768 pixel monitor.
·
GOSUB Get_Ping_Cm ' Get cm measurement
distance = distance MAX 100 / 4 ········ ' Scale for Debug Terminal
·
Now, we know the object's distance and angle relative to the Ping))) rangefinder on the front of the Boe-Bot. The problem is that these values are polar coordinates (distance ·angle), but the program needs to express them in terms of Cartesian coordinates (x, y) for Debug Terminal display. The Cartesian coordinates, are necessary for displaying the asterisks that denote the object's position in the Debug Terminal with the DEBUG command's CRSRXY formatter. So, the program calls the Polar_To_Cartesian subroutine. Given distance and angle, the subroutine calculates the corresponding x and y coordinates.
·
GOSUB Polar_To_Cartesian ' distance @ angle -> (x, y)
·
Before repeating the main routine's DO...LOOP, the last step is to plot an asterisk at the (x, y) coordinate. x will be a value that ranges from about -50 to 50. So, the x-coordinate in DEBUG CRSRXY is 50 + x. The y-coordinate will range from 0 to 25. However, CRSRXY will plot the value in terms of carriage returns down from the top line of the Debug Terminal. What we really want is carriage returns upward from the "X" that was plotted at 50 spaces over and 25 carriage returns down. That's why the CRSRXY formatter's y-coordinate is 25 - y. As y gets larger, the asterisk is plotted closer to the X at (50, 25). As y gets smaller, the asterisk is plotted closer to the top of the Debug Terminal.
·
' Display asterisk at x,y coordinate.
DEBUG CRSRXY, 50 + x, 25 - y, "*"
Advanced Topic − Inside the Polar_To_Cartesian Subroutine
Please see additional content posted below.
Post Edited By Moderator (Jessica Uelmen (Parallax)) : 8/25/2010 6:00:46 PM GMT
This activity features a program that displays what the Boe-Bot detects in the Debug Terminal as it sweeps the Ping))) rangefinder back and forth. Figure 1 shows an example with a cup and box set in the Boe-Bot's 180° field of detection along with their signatures displayed in the Debug Terminal. Experimenting with this program will help you better understand what the Boe-Bot can and cannot detect with the Ping))) Ultrasonic Rangefinder and Mounting Bracket, which is important for writing programs that navigate with this object detection system.
View Video Introduction – (YouTube)
Download Source Code – Ping)))Dar
Figure 2 shows a Boe-Bot assembled with the Ping))) Ultrasonic Rangefinder and Mounting Bracket kits. The mounting bracket kit makes it possible for the Boe-Bot to swivel the Ping))) rangefinder and measure object distances across a 180° field in front of it.
Figure 1: Seeing what the Boe-Bot Detects with Ping)))Dar.bs2
Figure 2: Boe-Bot with Ping))) Ultrasonic Rangefinder and Mounting Bracket Kit
·
Getting Started
This project contains advanced topics, not intended for Boe-Bot beginners. ·Before continuing, it is highly recommended you complete the following tasks in order to gain a better understanding on how this program operates:
√······· Complete all activities in What’s a Microcontroller
√······· Complete at minimum Chapters 1-4 in Robotics with the Boe-Bot
√······· Complete at minimum Chapters 1-3 in Smart Sensors and Applications
√······· Download the product documentation and assembly instructions for the PING))) Bracket Kit
Parts Required
(1) Fully assembled and tested Boe-Bot® Robot
(1) Ping))) Ultrasonic Rangefinder
(1) Ping))) Mounting Bracket Kit
Polar to Cartesian Coordinate Conversion
Ping)))Dar.bs2 will scan a 180° field in front of the Boe-Bot by incrementally rotating the Ping))) Mounting Bracket and then taking a distance measurement. It will do this rapidly enough that the mounting bracket servo will appear to just be rotating from right to left and back again as it updates the Debug Terminal display.
·
For each measurement in a given sweep, the information Ping)))Dar.bs2 will have to work with is a distance measurement (d) and an angle measurement (θ[noparse];)[/noparse] as shown in Figure 3. When coordinates are given in terms of distance and angle, they are called polar coordinates. These coordinates are typically expressed in parentheses like this: (d θ[noparse];)[/noparse]. When telling those coordinates to someone, you would normally say, "d at an angle of theta." In order to display these measurements graphically in the Debug Terminal, Ping)))Dar.bs2 will have to convert these polar coordinates to Cartesian (x, y) coordinates. That way, the DEBUG CRSRXY, x, y, "*" command can be used to graphically display the measurement by positioning the cursor and then placing an asterisk.
·
Figure 3: Object's Polar and Cartesian Coordinates
·······
Calculating the x and y axis components given polar coordinates is not difficult. The equations for x and y are shown below. The x-axis component involves multiplying the distance by the cosine of the angle, and the y component is the distance multiplied by the sine of the angle.
·
Since the BASIC Stamp is an integer math processor, the programming for making these conversions is a little different from what you might expect with a PC programming language. Ping)))Dar.bs2's Polar_To_Cartesian subroutine is explained in Advanced Topic − Inside the Polar_To_Cartesian Subroutine.
Assembly and Electrical Connections
√······· Follow the instructions in the Ping))) Mounting Bracket Documentation for making the mechanical and electrical connections to the servo and Ping))) Ultrasonic rangefinder. When you are done, the servo will be connected to the Board of Education's servo port 14, and the Ping))) rangefinder will be connected to port 15.
Mounting Bracket Adjustments
Keep in mind that Ping)))Dar.bs2 will measure distances and angles. Recall from What's a Microcontroller that a PULSOUT command's Duration argument sends a message to a standard servo telling it what rotational position to hold. In other words, the PULSOUT command's Duration argument tells the Ping))) mounting bracket's standard servo what angle to turn to.· Ping)))Dar.bs2 will need to convert the PULSOUT command's Duration argument to a binary radian measurement before the program can do polar to Cartesian coordinate conversion. Since the object's position is dependent on good distance and angle measurements, it will be important mechanically adjust and calibrate your Ping))) Mounting Bracket system so that the program's PULSOUT commands can sweep it from 0° (to the right) to 180° (to the left).· The first adjustment step toward good Ping))) Mounting Bracket servo angular control is making sure that the Ping))) rangefinder is mounted so that the servo points the Ping))) rangefinder straight ahead when the servo receives 1.5 ms center pulses.
·
√······· Run PingServoCenter.bs2.
√······· Make sure the Board of Education's 3-position power switch is set to position-2.
√······· Check to see whether the mounting bracket servo points the Ping))) rangefinder straight ahead on the Boe-Bot.
√······· If it does, then continue to the Software Calibration for 180° Sweep section.· Otherwise, keep following the checklist instructions here.
√······· Make sure CenterPing.bs2 is running for the remaining checklist instructions in this section.
√······· Start by removing the screw that connects the servo horn to the output shaft shown in Figure 4 (a).
√······· Pull upward on the Ping))) rangefinder. The horn, which is attached to the Ping))) rangefinder with screws should slide up and off the servo's output shaft, also shown in Figure 4 (a).
√······· Orient the Ping))) rangefinder so that it is pointing straight ahead as shown in Figure 4 (b).
√······· Slide the servo horn back onto the output shaft.
·
·
√······· Screw the screw back in that holds the servo horn to the Ping))) mounting bracket.
·Figure 4: Mounting the Ping))) Rangefinder so that It Points Straight Ahead
·······
√······· To adjust for any slight error caused by the output shaft to servo horn gear teeth alignment, start by loosening the screws that attach the servo to the Boe-Bot chassis.
√······· Now, you will have some wiggle room to rotate the servo's housing slightly to make up for any offset resulting from the alignment of the servo horn and output shaft's teeth.
√······· Make sure to re-tighten all the screws when you are done.
Example Program – PingServoCenter.bs2
[color=#008000]' Smart Sensors and Applications - PingServoCenter.bs2[/color] [color=#008000]' Send 1.5 ms "center" pulses to the servo the Ping))) rangefinder is[/color] [color=#008000]' attached to.[/color] [color=#008000]' {$STAMP BS2}[/color] [color=#008000]' {$PBASIC 2.5}[/color] [color=#000000]PingServo PIN 14 [/color][color=#008000]' Servo directs Ping)))[/color] [color=#000000]Center CON 750 [/color][color=#008000]'[/color] [color=#008000]Center/0-degree pulse duration[/color] [color=#000000]BtwnPulses CON 20 [/color][color=#008000]' ms between servo pulses[/color] [color=#020FC0]DO[/color] [color=#008000]' Main loop[/color] [color=#020FC0]PULSOUT[/color][color=#000000] PingServo, Center [/color][color=#008000]' Center signal -> Ping))) servo[/color] [color=#020FC0]PAUSE[/color][color=#000000] BtwnPulses [/color][color=#008000]' 20 ms delay between pulses[/color] [color=#020FC0]LOOP [/color] [color=#008000]' Repeat main loop[/color]
Software Calibration for 180° Sweep
The Boe-Bot needs to be able to point the Ping))) rangefinder from 0° (to the right) to 180° (to the left) as shown in Figure 5. The Ping))) mounting bracket's servo should direct the ping to 0° when it receives 0.5 ms pulses and to 180° when it receives 2.5 ms pulses. Since the PULSOUT command times pulse durations in terms of 2 μs units, the command PULSOUT 14, 250 will cause the servo to rotate the Ping))) rangefinder to 0°, and PULSOUT 14, 1250 will direct it to 180°.
Figure 5: Angle and Ping))) Rangefinder Direction
·······
The TestPingDirection.bs2 program declares LimitRight and LimitLeft as constants equal to 250 and 1250. The program also declares PingServo to be PIN 14 and Center to be 750. So the command PULSOUT PingServo, LimitRight should direct the rangefinder 0° to the right, and PULSOUT PingServo, LimitLeft direct the rangefinder 180°. Also, PULSOUT PingServo, Center should point the rangefinder straight ahead.
·
If the LimitLeft and LimitRight constants do not make the servo point the Ping))) rangefinder to 0° and 180°, the program's CON directive values should be adjusted. For LimitRight, values smaller than 250 will cause the servo to rotate further in the clockwise direction (to the right) while values larger than 250 will cause it to rotate to a position closer to center. Likewise, values greater than 1250 will cause the servo to rotate further in the counterclockwise direction (to the left) while values smaller that 1250 will cause it to rotate to a position closer to center.
·
√······· Run TestPingDirection.bs2 and make sure the servo points the Ping))) rangefinder to 0°, then to 180°, then to 90° (straight ahead).
√······· If the servo doesn't point to 0°, adjust the LimitRight constant accordingly.· Values less than 250 will result in more clockwise rotation and values greater than 250 will result in less clockwise rotation.
√······· If the servo doesn't point to 180° to the left, adjust the LimitLeft constant accordingly. Values greater than 1250 will result in more counterclockwise rotation, and values less than 1250 will result in less counterclockwise rotation.
√······· Update these CON directives, and make notes of the values you used. These same CON directives will have to be updated in this activity's Ping)))Dar.bs2 program and also in the next activity's GotoClosestObject.bs2 program.
Example Program – TestPingDirection.bs2
[color=#008000]' Smart Sensors and Applications - TestPingDirection.bs2[/color] [color=#008000]' Point the Ping))) 0-degrees (to the right), then 180-degrees (to the right),[/color] [color=#008000]' then straight ahead.[/color] [color=#008000]' {$STAMP BS2}[/color] [color=#008000]' {$PBASIC 2.5}[/color] [color=#000000]PingServo PIN 14 [/color][color=#008000]' Servo directs Ping)))[/color] [color=#000000]LimitLeft CON 1250 [/color][color=#008000]' Ping servo 90-degrees left[/color] [color=#000000]LimitRight CON 250 [/color][color=#008000]' Ping servo 90-degrees right[/color] [color=#000000]Center CON 750 [/color][color=#008000]' Center/0-degree pulse duration[/color] [color=#000000]BtwnPulses CON 20 [/color][color=#008000]' ms between servo pulses[/color] [color=#000000]counter VAR Byte [/color][color=#008000]' Loop index[/color] [color=#020FC0]DEBUG[/color] [color=#ff0000]"Look to 0-degrees (right)."[/color][color=#000000], [/color][color=#800080]CR[/color] [color=#020FC0]FOR[/color][color=#000000] counter = 1 [/color][color=#020FC0]TO[/color][color=#000000] 100 [/color][color=#008000]' 100 pulses 0-degrees (right)[/color] [color=#020FC0] PULSOUT[/color][color=#000000] 14, LimitRight[/color] [color=#020FC0] PAUSE[/color][color=#000000] 20[/color] [color=#020FC0]NEXT[/color] [color=#020FC0]DEBUG[/color] [color=#ff0000]"Look to 180-degrees (left)."[/color][color=#000000], [/color][color=#800080]CR[/color] [color=#020FC0]FOR[/color][color=#000000] counter = 1 [/color][color=#020FC0]TO[/color][color=#000000] 100 [/color][color=#008000]' 100 pulses 180-degrees (left)[/color] [color=#020FC0] PULSOUT[/color][color=#000000] 14, LimitLeft[/color] [color=#020FC0] PAUSE[/color][color=#000000] 20[/color] [color=#020FC0]NEXT[/color] [color=#020FC0]DEBUG[/color][color=#000000] "[/color][color=#ff0000]Look to 90-degrees (straight ahead)."[/color][color=#000000], [/color][color=#800080]CR[/color] [color=#020FC0]FOR[/color][color=#000000] counter = 1 [/color][color=#020FC0]TO[/color][color=#000000] 100 [/color][color=#008000]' 100 pulses 90-degrees (ahead)[/color] [color=#020FC0] PULSOUT[/color][color=#000000] 14, Center[/color] [color=#020FC0] PAUSE[/color][color=#000000] 20[/color] [color=#020FC0]NEXT[/color] [color=#020FC0]END[/color]
Testing Ping)))Dar
One of the most important things about Ping)))Dar.bs2 is that it will help give you a better idea of what the Boe-Bot "sees" as it sweeps the Ping))) rangefinder from left to right. Make sure to test a variety of objects at a variety of distances. Keep in mind also that the program is imposing a 100 cm distance limit on measurements to make the display more convenient.
·
Before running the program, the LimitRight and LimitLeft CON directives should be updated so that the servo that directs the Ping))) rangefinder to sweep from 0° to 180° using the values you determined with TestPingDirection.bs2.
·
Ping)))Dar converts the PULSOUT command's Duration arguments into binary radian servo rotation angle measurements with the help of a constant and the ** operator. Let's assume that LimitRight is 250 and LimitLeft is 1250. The main routine in Ping)))Dar.bs2 has code that sweeps the PULSOUT command's Duration argument from 250 to 1250 in increments of 15. As shown in Figure 6, that's about 2.7° for each increment of 15, which is pretty close to 2 brads (2.8125°).
·
Figure 6: Rotation Angle vs. PULSOUT Duration[/font][/size]
Mapping the PULSOUT command's duration argument to the number of brads the servo has rotated involves the ** operator. In the next example program, the command that does the job is angle = pingDir - LimitRight ** PingDirToAngle. The pingDir variable is used in the command PULSOUT PingServo, PingDir to point the Ping))) rangefinder to 0 brads (0°), then 2 brads, then 4 brads and so on all the way to 128 brads (180°). As it does this, the pingDir variable starts at LimitRight (250), then 265, then 280, and so on up through LimitLeft (1250).
Since the expression angle = pingDir - LimitRight ** PingDirToAngle subtracts LimitRight from pingDir before the ** operation, the value ** scales will range from 0 through 1000 instead of 250 to 1250. The PingDirToAngle constant has to be the right number of 65536ths to scale this range of 0 to 1000 into 0 through 128 brads. This is another job for the ** scale constant equation introduced in Chapter 3, Activity #3 in Smart Sensors and Applications
········
Here is an example of calculating PingDirToAngle constant when LimitRight is 250 and LimitLeft is 1250. Make sure to follow along because you will need to recalculate this constant based on the LimitLeft and LimitRight constants you determined for your mounting bracket system with TestPingDirection.bs2.· The number of output scale elements is 0 through 128, which is 129 elements since the range includes zero. Next, LimitLeft − LimitRight = 1250 − 250 = 1000. Again, we are talking about a range that's inclusive of 0, so there are really 1001 elements in the input scale.
·······
Substituting 129 and 1001 into the ** scale constant equation yields:
·······
Example Program – Ping)))Dar.bs2
Some of the checklist instructions below involve updating CON directives that you determined with TestPingDirection.bs2. While they are not necessarily crucial to this program, they will be crucial for GotoClosestObject.bs2, the Boe-Bot Ping))) Mounting Bracket navigation program in the next activity.
·
√······· Open Ping)))Dar.bs2 with your BASIC Stamp Editor.
√······· Update the LimitRight and LimitLeft CON directives in the program to tune the 0° right and 180° left pulse widths.
√······· If you changed either LimitLeft or LimitRight, calculate the value needed for the PingDirToAngle CON directive with the PingDirToAngle equation just discussed. Make sure to update this value in your program too.
√······· Make notes of all these CON directives because you will need to substitute them into the next activity's GotoClosestObject.bs2 example program.
√······· Run the program and maximize your Debug Terminal so that it takes up the entire computer screen.
√······· Observe the Debug Terminal as you try placing a variety of objects at various distances from the Boe-Bot at various locations in its 180° field of detection.
√······· Make sure to try the suggestions in the section after the example program entitled Your Turn - Understanding what the Boe-Bot Does and Does not "See".· It brings to light some of this setup's capabilities and drawbacks, and they turn out to be important for writing navigation programs.
[color=#008000]' -----[noparse][[/noparse] Title ]--------------------------------------------------------------[/color] [color=#008000]' Smart Sensors and Applications - Ping)))Dar.bs2[/color] [color=#008000]' Display radar style object distance measurements in the Debug Terminal.[/color] [color=#008000]' as the Boe-Bot sweeps the Ping))) Mounting Bracket servo from right[/color] [color=#008000]' (0-degrees) to left (180-degrees).[/color] [color=#008000]' {$STAMP BS2} ' Target device = BASIC Stamp 2[/color] [color=#008000]' {$PBASIC 2.5} ' Language = PBASIC 2.5[/color] [color=#008000]' -----[noparse][[/noparse] I/O Definitions ]----------------------------------------------------[/color] [color=#000000]PingServo PIN 14[/color][color=#008000] ' Servo that directs Ping)))[/color] [color=#000000]Ping PIN 15[/color][color=#008000] ' Ping))) sensor signal pin[/color] [color=#008000]' -----[noparse][[/noparse] Constants ]----------------------------------------------------------[/color] [color=#000000]LimitLeft CON 1250[/color][color=#008000] ' Bracket 90-degrees LimitLeft[/color] [color=#000000]LimitRight CON 250[/color][color=#008000] ' Bracket 90-degrees LimitRight[/color] [color=#000000]PingDirToAngle CON 8454[/color][color=#008000] ' Servo pulse -> angle with **[/color] [color=#000000]CmConstant CON 2260[/color][color=#008000] ' Echo time -> cm with **[/color] [color=#000000]SinCosTo256 CON 517[/color][color=#008000] ' For */ -127..127 -> -256..256[/color] [color=#000000]Increment CON 15[/color][color=#008000] ' Servo PULSOUT increment value[/color] [color=#000000]Negative CON 1[/color][color=#008000] ' Negative sign[/color] [color=#000000]Positive CON 0[/color][color=#008000] ' Positive sign[/color] [color=#008000]' -----[noparse][[/noparse] Variables ]----------------------------------------------------------[/color] [color=#000000]pingDir VAR Word[/color][color=#008000] ' Pulse duration -> direction[/color] [color=#000000]time VAR Word[/color][color=#008000] ' Ping))) echo time[/color] [color=#000000]distance VAR Time[/color][color=#008000] ' Object distance[/color] [color=#000000]x VAR Word[/color][color=#008000] ' x Debug cursor coordinate[/color] [color=#000000]y VAR Word[/color][color=#008000] ' y Debug cursor coordinate[/color] [color=#000000]angle VAR Byte[/color][color=#008000] ' Angle from LimitRight in brads[/color] [color=#000000]counter VAR angle[/color][color=#008000] ' Loop counter[/color] [color=#000000]sweepInc VAR Nib[/color][color=#008000] ' Sweep increment[/color] [color=#000000]sweepDir VAR Bit[/color][color=#008000] ' Increment/decrement pingDir[/color] [color=#000000]xSign VAR Bit[/color][color=#008000] ' x variable sign[/color] [color=#000000]ySign VAR xSign[/color][color=#008000] ' Stores sign of y variable[/color] [color=#000000]nsign VAR Bit[/color][color=#008000] ' Numerator sign[/color] [color=#000000]dsign VAR Bit[/color][color=#008000] ' Denominator sign[/color] [color=#008000]' -----[noparse][[/noparse] Initialization ]-----------------------------------------------------[/color] [color=#000000]pingDir = LimitRight[/color][color=#008000] ' Start servo at 0-degrees[/color] [color=#020FC0]FOR[/color] [color=#000000]counter = 1[/color] [color=#020FC0]TO[/color] [color=#000000]40[/color][color=#008000] ' Initialize servo position[/color] [color=#020FC0]PULSOUT[/color] [color=#000000]PingServo, pingDir[/color] [color=#020FC0] PAUSE [/color][color=#000000]20[/color] [color=#020FC0]NEXT[/color] [color=#000000]sweepInc = Increment[/color][color=#008000] ' Set the sweep increment[/color] [color=#008000]' -----[noparse][[/noparse] Main Routine ]-------------------------------------------------------[/color] [color=#020FC0]DO[/color] [color=#020FC0]IF[/color] [color=#000000]pingDir <= LimitRight[/color] [color=#020FC0]THEN[/color][color=#008000] ' Refresh display if far right[/color] [color=#020FC0]DEBUG[/color] [color=#800080]CLS[/color][color=#000000],[/color] [color=#800080]CRSRXY[/color][color=#000000],[/color] [color=#000000]50, 25,[/color] [color=#ff0000]"X"[/color] [color=#020FC0]ENDIF[/color] [color=#020FC0]GOSUB[/color] [color=#000000]Sweep_Increment[/color][color=#008000] ' Move servo by sweepInc[/color] [color=#008000] ' Calculate angle from far right in brads.[/color] [color=#000000]angle = pingDir - LimitRight ** PingDirToAngle[/color] [color=#020FC0]GOSUB[/color] [color=#000000]Get_Ping_Cm[/color][color=#008000] ' Get cm measurement[/color] [color=#000000]distance = distance MAX 100 / 4[/color][color=#008000] ' Scale for Debug Terminal[/color] [color=#020FC0]GOSUB[/color][color=#008000] Polar_To_Cartesian ' distnace @ angle -> (x, y)[/color] [color=#008000] x = x * 2 ' 2 spaces for every 1 CR[/color] [color=#020FC0]DEBUG[/color] [color=#800080]CRSRXY[/color][color=#000000], 50 + x, 25 - y,[/color] [color=#ff0000]"*" [/color][color=#008000] ' Display (x, y) coordinate[/color] [color=#020FC0]LOOP[/color] [color=#008000]' -----[noparse][[/noparse] Subroutine - Get_Ping_Cm ]-------------------------------------------[/color] [color=#008000]' Gets Ping))) rangefinder measurement and converts time to centimeters.[/color] [color=#008000]' Distance may be declared as time to save variable space.[/color] [color=#000000]Get_Ping_Cm:[/color] [color=#020FC0]PULSOUT[/color] [color=#000000]Ping, 5[/color] [color=#020FC0]PULSIN[/color] [color=#000000]Ping, 1, time[/color] [color=#000000]distance = time ** CmConstant[/color] [color=#020FC0]RETURN[/color] [color=#008000]' -----[noparse][[/noparse] Subroutine - Polar_To_Cartesian ]------------------------------------[/color] [color=#008000]' Calculates x and y (Cartesian coordinates) given distance and angle[/color] [color=#008000]' (polar coordinates).[/color] [color=#008000]Polar_To_Cartesian:[/color] [color=#008000] ' Calculate x coordinate.[/color] [color=#000000]x = COS angle [/color][color=#008000]' Polar to Cartesian[/color] [color=#000000]xSign = x.BIT15 [/color][color=#008000]' Store sign bit[/color] [color=#000000]x = ABS(x) */ SinCOsTo256 [/color][color=#008000]' Polar to Cartesian continued[/color] [color=#000000]x = distance */ x[/color] [color=#020FC0]IF[/color] [color=#000000]xSign = negative [/color][color=#020FC0]THEN[/color] [color=#000000]x = -x [/color][color=#008000]' Correct sign with sign bit[/color] [color=#008000] ' Calculate y coordinate.[/color] [color=#000000]y = SIN angle[/color][color=#008000] ' Polar to Cartesian[/color] [color=#000000]ySign = y.BIT15[/color][color=#008000] ' Store sign bit[/color] [color=#000000]y = ABS(y) */ SinCOsTo256[/color][color=#008000] ' Polar to Cartesian continued[/color] [color=#000000]y = distance */ y[/color] [color=#020FC0]IF[/color] [color=#000000]ySign = negative[/color] [color=#020FC0]THEN[/color] [color=#000000]y = -y[/color][color=#008000] ' Correct sign with sign bit[/color] [color=#020FC0]RETURN[/color] [color=#008000]' -----[noparse][[/noparse] Subroutine - Sweep_Increment ]---------------------------------------[/color] [color=#008000]' Increment/decrement the position of the servo that directs the Ping)))[/color] [color=#008000]' rangefinder. When pingDir goes outside either LimitRight or LimitLeft,[/color] [color=#008000]' the sweep direction toggles.[/color] [color=#000000]Sweep_Increment:[/color] [color=#008000] ' Change sweepDir for adding/subtracting increment if at rotation limit.[/color] [color=#020FC0]IF[/color] [color=#000000]pingDir <=[/color][color=#008000] LimitRight [/color][color=#020FC0]THEN[/color] [color=#000000]sweepDir = Positive[/color] [color=#020FC0]ELSEIF[/color] [color=#000000]pingDir >= LimitLeft[/color] [color=#020FC0]THEN[/color] [color=#000000]sweepDir = Negative[/color] [color=#020FC0]ENDIF[/color] [color=#008000] ' Add/subtract increment to/from pingDir.[/color] [color=#020FC0]IF[/color] [color=#000000]sweepDir = negative[/color] [color=#020FC0]THEN[/color] [color=#000000]pingDir = pingDir - sweepInc[/color] [color=#020FC0]ELSEIF[/color] [color=#000000]sweepDir = Positive[/color] [color=#020FC0]THEN[/color] [color=#000000]pingDir = pingDir + sweepInc[/color] [color=#020FC0]ENDIF[/color] [color=#008000] ' Send positioning pulse to Ping))) Mounting Bracket servo.[/color] [color=#020FC0]PULSOUT[/color] [color=#000000]PingServo, pingDir[/color] [color=#020FC0]RETURN[/color]
Your Turn - Understanding what the Boe-Bot does and does not "See"
To understand what your Boe-Bot does and does not "see" with the Ping))) rangefinder, a few experiments are in order. Here are some questions that can be answered with Ping)))Dar.bs2 and various objects placed in the Boe-Bot's field of detection.
·
√······· If you place one object behind another object, can it see the object in back?
√······· How far do you have to rotate a flat object before it is no longer visible to Ping)))?
√······· Start with one or two cylindrical objects about 3 ft (91 cm) apart and 2 ft (61 cm) from the front of the Boe-Bot.
√······· As you move the objects closer to each other, how close can they be to each other before they appear to be one object in the Debug Terminal?
√······· If you keep the objects the same distance from each other but move them closer to the front of the Boe-Bot, is the gap between them detected again at some point?
√······· To what extent does setting the Increment constant is set to a smaller value help the Boe-Bot detect the gap between objects?
How Ping)))Dar.bs2 Works
The initialization routine applies forty pulses to make sure the servo turns and starts 0° (far-right). In this program, the FOR...NEXT loop is only used once. In GoToClosestObject.bs2 in the next activity, the loop is used frequently to point the Ping))) rangefinder in various directions, so in that program, the loop is placed in a subroutine called Point_At_PingDir. One other initialization detail is setting the sweepInc variable equal to the Increment constant (15). This value is used by the Sweep_Increment subroutine to rotate the Ping))) Mounting Bracket servo slightly between each distance measurement.
·
pingDir = LimitRight ··················· ' Start servo at 0-degrees
·
FOR counter = 1 TO 40 ·················· ' Initialize servo position
· PULSOUT PingServo, pingDir
· PAUSE 20
NEXT
·
sweepInc = Increment ··················· ' Set the sweep increment
·
The main routine's DO...LOOP refreshes the Debug Terminal display after each right-left sweep. As the main routine's DO...LOOP repeats, the first thing the program does is clear the Debug Terminal and place the "X" character at 50 spaces over and 25 carriage returns down. This "X" indicates the Boe-Bot's position.
·
IF pingDir <= LimitRight THEN ·········· ' Refresh display if far right
· DEBUG CLS, CRSRXY, 50, 25, "X"
ENDIF
·
Next, the program calls the Sweep_Increment subroutine, which adjusts the Ping))) Mounting Bracket's servo slightly each time it gets called. Calling this subroutine repeatedly each time through the main routine's DO...LOOP results in the back and forth sweeping motion. This subroutine uses the pingDir variable to direct the servo.
GOSUB Sweep_Increment ·················· ' Move servo by sweepInc
·
The Sweep_Increment subroutine modified the value of pingDir, and then used it in a PULSOUT command's Duration argument to point the Ping))) Mounting Bracket servo in a new direction. That means we can use the value of pingDir to determine the angle to which the Ping))) rangefinder is pointing in terms of binary radians.
·
Figure 7 shows a few examples of how the PULSOUT command's Duration argument relates to the Ping))) Mounting Bracket servo's rotational position. For example, when pingDir is LimitRight, (250), the angle is 0°, which is 0 binary radians (brads). When pingDir is 500, the angle is about 45°, or 32 brads. Likewise, pingDir can be 750 or1000, and the respective servo angles will be 90° (64 brads) and 135° (96 brads). By the time pingDir gets to LimitLeft (1250), the angle will be 180° = 128 brads.
Figure 7: PULSOUT Duration Argument vs. Rotation Angle
·······
Here is the command that converts pingDir, which ranges from LimitRight to LimitLeft (250 to 1250) to angle, which ranges from 0 to 128 brads. Note that this is the same kind of equation we used in Chapter 3, Activity #3 and #4.
·
' Calculate angle from far right in brads.
angle = pingDir - LimitRight ** PingDirToAngle
·
Without parentheses, PBASIC executes operators from left to right. So the command angle = pingDir - LimitRight ** PingDirToAngle first subtracts LimitRight from pingDir. This resulting value, which could be anywhere from 0 through 1000, has the ** PingDirToAngle operation performed on it. Since PingDirToAgle is 8454 in the example program, it means a value from 0 through 1000 gets multiplied by 8454 / 65536.· If pingDir stores 1000, the result is 128.9978, and the ** operator rounds it down to 128, which is the correct number of brads assuming the servo is in fact pointing left (180° from far right).· Likewise, (750 - 250) × 8454 / 65536 results is 64.4989, which rounds down to 64 brads, which is 90°, and the servo should be pointing straight ahead.
·
Next, the distance of the object at the angle the Ping))) Mounting Bracket servo is pointing to gets measured and scaled to a centimeter measurement. This centimeter measurement is further scaled down by 1/4 of its actual value to make it fit more conveniently in a Debug Terminal maximized in a typical 1024 by 768 pixel monitor.
·
GOSUB Get_Ping_Cm ' Get cm measurement
distance = distance MAX 100 / 4 ········ ' Scale for Debug Terminal
·
Now, we know the object's distance and angle relative to the Ping))) rangefinder on the front of the Boe-Bot. The problem is that these values are polar coordinates (distance ·angle), but the program needs to express them in terms of Cartesian coordinates (x, y) for Debug Terminal display. The Cartesian coordinates, are necessary for displaying the asterisks that denote the object's position in the Debug Terminal with the DEBUG command's CRSRXY formatter. So, the program calls the Polar_To_Cartesian subroutine. Given distance and angle, the subroutine calculates the corresponding x and y coordinates.
·
GOSUB Polar_To_Cartesian ' distance @ angle -> (x, y)
·
Before repeating the main routine's DO...LOOP, the last step is to plot an asterisk at the (x, y) coordinate. x will be a value that ranges from about -50 to 50. So, the x-coordinate in DEBUG CRSRXY is 50 + x. The y-coordinate will range from 0 to 25. However, CRSRXY will plot the value in terms of carriage returns down from the top line of the Debug Terminal. What we really want is carriage returns upward from the "X" that was plotted at 50 spaces over and 25 carriage returns down. That's why the CRSRXY formatter's y-coordinate is 25 - y. As y gets larger, the asterisk is plotted closer to the X at (50, 25). As y gets smaller, the asterisk is plotted closer to the top of the Debug Terminal.
·
' Display asterisk at x,y coordinate.
DEBUG CRSRXY, 50 + x, 25 - y, "*"
Advanced Topic − Inside the Polar_To_Cartesian Subroutine
Please see additional content posted below.
Post Edited By Moderator (Jessica Uelmen (Parallax)) : 8/25/2010 6:00:46 PM GMT
Comments
I am unable on multiple attenpts to download the attached file(s) in the ZIP attachment. Are the code and PDF still available? Thanks.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Given a distance at an angle (d··θ[noparse];)[/noparse], you can calculate the x and y coordinates (x, y) with the help of a calculator and these two formulas:
Calculating x and y with the BASIC Stamp involves the SIN, COS, and */ operators.
·
√······· Look up and review the */, SIN and COS operators in either the BASIC Stamp Manual or the BASIC Stamp Editor's Help feature
Given an angle in brads, PBASIC's COS operator returns 127 to 0 to -127 to 0 as the brad angle goes from 0 to 64 to 128 to 192. Calculating the cosine from 0° to 90° to 180° to 270° with a calculator will yield results that range from 1 to 0 to -1 and back to 0 again. The SIN operator behaves similarly, returning values that range from 0 to 127 to 0 to -127 as the angle in brads goes from 0 to 64 to 128 to 192. Again, if you calculate the sine of angles from 0° to 90° to 180° to 270° with a calculator, you will see that the actual sine values range from 0 to 1 to 0 to -1. The problem here is that we want to multiply distance results for SIN and COS values that range from -1 to 1, not -127 to 127.
One way around this is creative use of the */ operator. This operator multiples a value by a number of 256ths. By using the */ operator twice, we can first scale a value in the range of -127 through 127 up to a range from -256 through 256. Then, we can use */ again to multiply that result by the distance. The second time, the */ operator will be multiplying the distance variable by sine and cosine values that are in terms of a number of 256ths. The result will be very close to what you would get from a calculator, multiplying the distance sine and cosine value that range from -1 through 1.·
To scale a value that will fall in the range of -127 through 127 to its equivalent in the range from -256 to 256, we'll use the */ scale constant equation introduced in Chapter 3, Activity #5 in Smart Sensors and Applications.
········
Since the input range is -127 through 127, that's 255 possible values. The output range is going to be -256 to 256, which is 513 possible values.
········
To calculate a constant we'll call SinCosTo256, we'll substitute 255 and 513 into the */ scale constant equation:
·········
Now that we know SinCosTo256 has to be 517, here is the routine for polar to Cartesian coordinate conversion. Notice that the sign of both the cosine and sine calculations are stored in the xSign and ySign bits, and the rest of the calculations are done with the absolute values of x and y. That's because /, */, //, and ** were designed to be used with positive integers only. So, the absolute value of each measurement is taken first.· Then the rest of the operations are done on the positive integer values, and the sign of the x and y results are restored at the end by IF...THEN statements.
·
' Calculate x coordinate.
x = COS angle ·························· ' Polar to Cartesian
xSign = x.BIT15 ························ ' Store sign bit
x = ABS(x) */ SinCOsTo256 ·············· ' Polar to Cartesian continued
x = distance */ x
IF xSign = negative THEN x = -x ········ ' Correct sign with sign bit
·
' Calculate y coordinate.
y = SIN angle ·························· ' Polar to Cartesian
ySign = y.BIT15 ························ ' Store sign bit
y = ABS(y) */ SinCOsTo256 ·············· ' Polar to Cartesian continued
y = distance */ y
IF ySign = negative THEN y = -y ········ ' Correct sign with sign bit
·
Post Edited By Moderator (Jessica Uelmen (Parallax)) : 8/25/2010 6:02:24 PM GMT
You should be able to download the zipped file from the link in the first post.
If just clicking on the link doesn't work, please try the following:
1- right click (contextual) on the link
2- select "Save Target as..."
3- In the "Save As" window specify where you want the file to be saved in your computer.
4- Once you have the file in your computer you can just UnZip it and see the content.
Regards,
Post Edited By Moderator (Jessica Uelmen (Parallax)) : 3/13/2009 3:33:14 PM GMT
Can you give a timeframe for the release of the text/course?
Thanks.
Thanks for the ideas. I tried everything that you have recommended, to no avail. It shows a "valid" ZIP file, with a 1.11MB file size. But when opened, it shows "0 files and 0 bytes". Latest version of WinZip, never had this problem with all the thousands of zip downloads I have accessed. But thanks for the ideas. And Andy has provided me with a solution. Thanks to Andy as well!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Thanks for your interest. Andy is totally done with this book. Now it’s in the editorial pipeline. Since the release of the Propeller™ microcontroller we’re been assigning higher priority to Propeller related books, as Propeller Manual and Hydra manual.
Our editor is getting close to finishing a huge job right now and next in the list is Smart Sensors and Applications. We are trying to finish this Stamps in Class book as soon as possible.
As soon as·we have a firm deadline we’re going to announce it in this forum (meanwhile you can keep accessing the pieces that form this book through forum posts as this one and the ones in this thread https://forums.parallax.com/discussion/82013).
Regards,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Aristides Alvarez
Education and Technical Support Manager
Parallax, Inc.
From the picture, this certainly looks to be the case (close range), so how does one get so many data points? Even if it had a 20 angle beam, objects would "appear" much wider and the accuracy would be much less. That's why the laser rangers with .3 degree or so detection beam cost over $1000. Can anyone explain this?
Post Edited (Andy Lindsay (Parallax)) : 9/21/2006 4:21:59 AM GMT
What happens with radar style sonar if the robot is in a sort of enclosure like a closet? Can it detect whats behind? I would imaging with a full rotation servo and extra wire it could work...
A "quick and easy" approach would be to stack two standard servos on top of each other. The bottom servo has a little over 180 degrees in rotation for +/- 90 degrees. The one on top has an additional 180-degrees for +/- 180 degrees. For example, to look behind you to 170 degrees to the left, turn the bottom servo 90 degrees to the left, and the top servo 80 degrees to the left. For that matter, you could simply direct both of them to turn 85-degrees left, and potentially save a variable.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
I am not volunteering by the way.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Check out my robot using the propeller robot.tmcp.com.au
If you offer cheap PCB fabrication, perl programming or any other helpful services please email me at.
anthonybmyatt@yahoo.com.au
· Could you mount two pings back-to-back, and fire them independantly (so they don't confuse each other) ?
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
“The United States is a nation of laws -· poorly written and randomly enforced.” - Frank Zappa
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.hittconsulting.com
·
That should be interesting. Pan and tilt servos are easy enough. The interesting part will be coming up with an algorithm that resolves successive measurements into a better representation of the object's shape.
Bean,
Either the Propeller or SX microcontrollers could deliver simultaneous pulses and track the echo times. The question is, will one Ping))) sensor get confused by the echo from the other Ping))) sensor's echo if it gets there first. I'm assuming it won't be a problem since the sound is coming from the opposite direction and getting blocked by the PCB, but we won't know until somebody tests it.
Andy
P.S. Bean, I read your message again after clicking Submit and realized that I misunderstood the question (and the point of the question).· Yes, if one Ping))) sensor starts after the other has finished its measurement, the robot will have 360 degree ultrasonic object detection with a BASIC Stamp 2 at the helm.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Post Edited (Andy Lindsay (Parallax)) : 6/11/2007 3:06:07 PM GMT
We've updated the Ping)))Dar project to include a brief video introduction/demonstration for your viewing pleasure.· You can check it out on YouTube here.
Happy Developing!
Jessica
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jessica Uelmen
Education Department
Parallax, Inc.
Post Edited (Jessica Uelmen (Parallax)) : 4/13/2009 4:50:38 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Whit+
"We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths." - Walt Disney
Glad you enjoyed it,
Jessica
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jessica Uelmen
Education Department
Parallax, Inc.
Thanks in advance,
Nick
· In the very first post you have images of several equations. In each of them the value 66536 is used. I beleive these should be 65536.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
There is a fine line between arrogance and confidence. Make sure you don't cross it...
·
It is listed as 65535ths in the text (following fig. 6), 66536 in the equations (also following fig. 6 and the 65535ths note) and then as 65536 further along in the text (following fig. 7).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Whit+
"We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths." - Walt Disney
Jessuca
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jessica Uelmen
Education Department
Parallax, Inc.
It looks like the second paragraph after figure #6 still says " 65535ths "
Not trying to be a pain....
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Whit+
"We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths." - Walt Disney
Thanks Whit! It's those little things that just slip by... All should be right with the forum post now.
Jessica
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jessica Uelmen
Education Department
Parallax, Inc.
Theoretically, it should be possible, but you'll want to look out for delays. You may not get as good of a "sweep" with PING)))Dar since the program won't be able to move as quickly through the main program. Using a separate interface to display Boe-Dar results will take more processing time, possibly leading to some missed displays from both PING)))Dar and Boe-Dar.
But this shouldn't discourage you from trying! First try combining each of the programs and see what happens, if there are any problems, identify what the issues might be and then modify the code to account for those issues. You may want to run two Ping)))Dar sweeps in order to get a better depiction of the area.
Happy Developing!
Jessica
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jessica Uelmen
Education Department
Parallax, Inc.
I have converted your PING)))Dar program from BS2 Basic to Propeller (spin).· Actually, I have to give a lot of credit to LOCALROGER.· He wrote the scailing code for the triginomic functions.· If you want, I can post here or on the Propeller thread.· I have a slight timing problem that I should have fixed soon.· I also·have to add a schematic at the beginning of the top object and add a lot of comments.·· I unloaded much of the scanning and Pinging into a cog.· The math and PST plotting is done in cog 0.· Hopefully, I will have it ready by this weekend (really busy at work).· Have a good one.
Bob
- I originally was going to use FLOAT32 math for the polar to Cartesian procedure, but found that integer math (using scaling) prove to be faster (BIG THANKS TO LOCALROGER).· Understand, if you want to use FLOAT32, it will still work.· If you want more info on using scaling, see the post I started in the "propeller" forum.· Title is "Debug, and plotting a "*" at a specific location".· Look for a post by LOCALROGER.· The beginning of this thread also explains it very well (THANKS JESSICA AND ANDY).
- If you want, you can use the scan routine for a robot.
- All math and plotting is done in the top object and the scanning/ranging is done in a cog.· I use pointers to read the values from the cog ("RANGE AND PINGDIR").
- Ensure you power ping and ping_servo with a good +5 volt supply.· Otherwise ping might just stop scanning without explanation.
- The whole project consists of 4 objects; "radar1", "FullDuplexSerialPlus", "ping_sweep_range", and "ping".·
- There are·a few·constants that you will have to modify... the first is in "radar1"... the value of "410", which is the value that corresponds to 1 msec and moves·MY servo to 0 degrees, you will have to change to match your 0 degrees.· Just plug in some values around 410 and see which one gets you closest to 0 degrees.·
- The second change is in the object "ping_sweep_range".· Change the con "LimitRight" to the value you used to replace my value of 410 (above).· You will also have to change "LimitLeft = 2330".· This is the value that corresponds to 2 msec and moves·MY servo to 180 degrees.· Once again, plug in some values (around 2330), and see which value gets you closest to 180 degrees.
- THIS IS IMPORTANT... YOU WILL ALSO HAVE TO CHANGE YOUR INCRIMENT VALUE (AND ANY VALUE of 1920 IN "radar1") IF THE DIFFERENCE BETWEEN LIMITRIGHT AND LIMIT LEFT DOES NOT EQUAL 1920.· If you have questions about this, please PM me, but you should be able to figure it out if you think about it.
- Schmatic is in top object ("radar1").· I used P0(servo) and P1(ping).· If you use different values, ensure you change them·in both "radar1" and "ping_sweep_range"
- One last thing... when you press F10 (or F11), you have a few seconds to press enable on PST.· Don't for get to "ENLARGE" the display (top right).
- I intend to use the scanning procedure on my bot.· I would not have been able to do this if previous documentation had not been complete.· Thanks again Jessica and Andy.
Have a good one.
Bob
Bob