Ping)))Dar Go To & Find Closest Object Issues
Rocko
Posts: 8
I have the Ping)))Dar Go To & Find Closest Object program up & running on my Boe-Bot but need some help with a couple of things.
The PingDar works as it should: scans, locates each side then middle of object, aligns wheels accordingly. Then it starts forward toward object but only gets several inches before it stops and repeats the scanning/locating sequence again. Then it starts forward again and only goes another couple of inches before it stops and starts the scan again. This process continues again and again.
I have to make note here that the object is only a 1-1/2" sq. wooden block, so when the PingDar gets to within ~6", it looses "site" of the object.
Does anyone know how I can modify the code so the PingDar only makes a couple of scans and after the second scan move forward indefinitely ?
I've tried modifying the code every which way but I'm at a loss on trying to get out of this loop.
Here's the code:
Thanks for your help!
The PingDar works as it should: scans, locates each side then middle of object, aligns wheels accordingly. Then it starts forward toward object but only gets several inches before it stops and repeats the scanning/locating sequence again. Then it starts forward again and only goes another couple of inches before it stops and starts the scan again. This process continues again and again.
I have to make note here that the object is only a 1-1/2" sq. wooden block, so when the PingDar gets to within ~6", it looses "site" of the object.
Does anyone know how I can modify the code so the PingDar only makes a couple of scans and after the second scan move forward indefinitely ?
I've tried modifying the code every which way but I'm at a loss on trying to get out of this loop.
Here's the code:
' -----[ Title ]-------------------------------------------------------------- ' Smart Sensors and Applications - GoToClosestObject.bs2 ' Sweep Ping))) Ultrasonic Rangefinder across 180-degrees and find the closest ' object. Then calculate and execute the turn required to face the object. ' Travel forward until the object is less than or equal to 5 cm from the front ' of the rangefinder. ' IMPORTANT: This program has several constants that have to be tuned before ' it will work right. Follow the instructions in Smart Sensors ' and Applications, Chapter 8, Activity #4 and #5 before you run ' this program! ' {$STAMP BS2} ' Target device = BASIC Stamp 2 ' {$PBASIC 2.5} ' Language = PBASIC 2.5 ' -----[ I/O Definitions ]---------------------------------------------------- ' Ping))) Ultrasonc Rangefinder and Mounting Bracket PingServo PIN 14 ' Servo that directs Ping))) snsr Ping PIN 1 ' Ping))) sensor signal pin ' Boe-Bot servo pins (Left and right are from driver's seat perspective.) BotServoLeft PIN 13 ' Left drive servo BotServoRight PIN 12 ' Right drive servo StartLED PIN 0 ' display start delay ' -----[ Constants ]---------------------------------------------------------- ' Ping))) mounting bracket constants LimitLeft CON 1189 ' Bracket 90-degrees Left LimitRight CON 286 ' Bracket 90-degrees Right Limits CON LimitLeft + limitRight 'this added from Forum Center CON 750 ' Center/0-degree pulse duration Increment CON 15 ' Increment for pulse sweeping MinSweep CON 40 ' Pulses -> 90-degree right ' Boe-Bot continuous rotation servo control constants FwdLeftFast CON 817 ' Fast settings - straight ahead FwdRightFast CON 650 RotateRight CON 763 ' Boe-Bot rotate right pulse RotateLeft CON 740 ' Boe-Bot rotate left pulse BtwnPulses CON 20 ' ms between servo pulses ' Ping))) Ultrasonic Rangefinder constants CmConstant CON 2260 ' Echo time -> cm with ** SinCosTo256 CON 517 ' For */ -127..127 -> -256..256 Ms20 CON 330 ' 20 ms worth of cm ' MSB sign (twos complement) Negative CON 1 ' Negative sign (bit-15) Positive CON 0 ' Positive sign (bit-15) ' Ping and turning axis geometry PingDirToAngle CON 8454 ' Servo pulse to angle ** con PingAxleOffset CON 7 ' 7 cm between ping))) and axis ' -----[ Variables ]---------------------------------------------------------- time VAR Word ' Ping))) echo time pingDir VAR Word ' Pulse duration -> direction pingRev VAR Word ' Pulse duration -> direction for reversed servo ' added from Forum x VAR Word ' x coordinate y VAR Word ' y coordinate distance VAR Time ' Object centimeter distance markDir VAR y ' Pulse points to closest object rightMark VAR x ' Pulse to object's right side leftMark VAR pingDir ' Pulse to object's left side pulses VAR x ' +/- brads to turn toward object PrevDist VAR Byte ' Previous distance measurement angle VAR Byte ' Servo angle from right in brads counter VAR angle ' Loop counter minDist VAR angle ' Minimum distance measurement sweepInc VAR Nib ' Increment for servo sweep sweepDir VAR Bit ' Increment/decrement pingDir xSign VAR Bit ' Stores sign of x variable ySign VAR xSign ' Stores sign of x variable pSign VAR Bit ' Sign of pulses variable edgesFound VAR Bit ' Navigation flag temp VAR Byte ' -----[ Initialization ]----------------------------------------------------- ' -----[ EEPROM Data ]----------------------------------------------------- RunStatus DATA $00 ' run status ' -----[ Initialization ]-------------------------------------------------- Reset: READ RunStatus, temp ' read current status temp = ~temp ' invert status WRITE RunStatus, temp ' save for next reset IF (temp > 0) THEN END ' run now? Start_Delay: HIGH StartLED ' show active PAUSE 5000 ' start delay LOW StartLED ' LED off ' following from Forum pingDir = LimitRight ' Start servo at 0-degrees FOR counter = 1 TO 40 ' Initialize servo position 'PULSOUT PingServo, pingDir ' Forum: removed & replaced by next 2 lines pingRev = Limits - pingDir PULSOUT PingServo, pingRev PAUSE 20 NEXT sweepInc = Increment ' Set the sweep increment ' -----[ Main Routine ]------------------------------------------------------- GOSUB Get_Ping_Cm ' First distance measurement DO UNTIL distance <= 5 ' Repeat until distance <= 5 cm edgesFound = 0 ' Clear edges found flag DO UNTIL edgesFound = 1 ' Repeat until edges found = 1 GOSUB Face_Closest_Object ' Find & face closest object LOOP GOSUB Get_Ping_Cm ' Get current distance DO UNTIL distance <= 5 ' Drive toward object prevDist = distance MAX 255 ' Current distance -> previous GOSUB Get_Ping_Cm ' Get new distance PULSOUT BotServoLeft, FwdLeftFast ' Boe-Bot forward PULSOUT BotServoRight, FwdRightFast PAUSE BtwnPulses - (distance / Ms20) ' 20 ms pause between pulses IF distance >= prevDist + 5 THEN EXIT ' Exit if distance increasing LOOP LOOP ' Main routine's outermost loop END ' -----[ Subroutines - BoeBot_Turn_Brads ]----------------------------------- ' Boe-Bot turns a certain number of binary radians to face an object. BoeBot_Turn_Brads: IF pSign = Positive THEN FOR counter = 0 TO ABS(pulses) PULSOUT BotServoLeft, RotateRight PULSOUT BotServoRight, RotateRight PAUSE BtwnPulses - (distance / Ms20) NEXT ELSE FOR counter = 0 TO ABS(pulses) PULSOUT BotServoLeft, RotateLeft PULSOUT BotServoRight, RotateLeft PAUSE BtwnPulses - (distance / Ms20) NEXT ENDIF RETURN ' -----[ Subroutines - Face_Closest_Object ]---------------------------------- ' Scan for closest object using a Ping))) rangefinder mounted on a standard ' servo. Locate the middle fo the object, and turn Boe-Bot to face it. Face_Closest_Object: ' Initialize sweep increment. sweepInc = Increment ' Start Servo rotated to the far right. pingDir = LimitRight GOSUB Point_At_PingDir ' Make minDist large and sweepDir positive (0). Single_Sweep sweeps ' left -> right while measuring object distances and stores the direction ' of the closest object in markDir. minDist = 65535 sweepDir = Positive GOSUB Single_Sweep ' Point the servo in the direction of the closest distance measurement. pingDir = markDir GOSUB Point_At_PingDir ' Scan to find object's right side. GOSUB Find_Right_Side IF edgesFound = 0 THEN RETURN ' Point the servo in the direction of the closest distance measurement. pingDir = markDir GOSUB Point_At_PingDir ' Scan to find object's right side. GOSUB Find_Left_Side IF edgesFound = 0 THEN RETURN ' Average the angles to the object's left and right sides. That's the ' middle of the object. Point rangefinder in that direction. pingDir = leftMark + rightMark / 2 GOSUB Point_At_PingDir ' At this point, the Ping))) should be pointing directly at the closest ' object. ' Calculate the angle to the object's angle in brads, and turn the ' Boe-Bot to face that angle. GOSUB Turn_Angle_Adjust GOSUB BoeBot_Turn_Brads ' Face Ping))) rangefinder straight ahead. pingDir = Center GOSUB Point_At_PingDir RETURN ' -----[ Subroutines - Find_Left_Side ]--------------------------------------- ' Scan left until the measured distance is 10 cm beyond the closest distance, ' which is assumed to mean the object's side has been found. ' If the object's side has been found within the 180-degree field of vision, ' set edgesFound = 1 and store the pulse duration (pingDir) at which the ' object was found in the leftMark variable. ' If the side was not found by the 180-degree point in the scan, rotate the ' Boe-Bot until the edge is found, and then set edgesFound to 0 signifying ' that the scan will have to be repeated because the Boe-Bot rotated ' to find the side, which would otherwise cause the markDir variable to ' store an incorrect value. Find_Left_Side: sweepDir = Positive distance = minDist sweepInc = 1 DO UNTIL distance > minDist + 10 GOSUB Sweep_Increment GOSUB Get_Ping_Cm IF pingDir >= LimitLeft - 10 THEN pingDir = LimitLeft - 50 GOSUB Point_At_PingDir DO UNTIL distance > minDist + 10 PULSOUT BotServoLeft, RotateLeft PULSOUT BotServoRight, RotateLeft GOSUB Get_Ping_Cm PAUSE 20 LOOP edgesFound = 0 RETURN ENDIF LOOP leftMark = pingDir edgesFound = 1 RETURN ' -----[ Subroutines - Find_Right_Side ]-------------------------------------- ' Mirror image of Find_Left_Side. Find_Right_Side: sweepDir = Negative distance = minDist sweepInc = 1 DO UNTIL distance > minDist + 10 GOSUB Sweep_Increment GOSUB Get_Ping_Cm IF pingDir <= LimitRight + 10 THEN pingDir = LimitRight + 50 GOSUB Point_At_PingDir DO UNTIL distance > minDist + 10 PULSOUT BotServoLeft, RotateRight PULSOUT BotServoRight, RotateRight GOSUB Get_Ping_Cm PAUSE 20 LOOP edgesFound = 0 RETURN ENDIF LOOP rightMark = pingDir edgesFound = 1 RETURN ' -----[ Subroutine - Get_Ping_Cm ]------------------------------------------- ' Gets Ping))) rangefinder measurement and converts time to centimeters. ' Distance may be declared as time to save variable space. Get_Ping_Cm: PULSOUT Ping, 5 PULSIN Ping, 1, time distance = time ** CmConstant RETURN ' -----[ Subroutines - Point_At_PingDir ]------------------------------------- ' Points servo mounted Ping))) rangefinder at an angle determined by the ' value of the pingDir variable. Point_At_PingDir: FOR counter = 0 TO MinSweep ' PULSOUT PingServo, pingDir ' Forum: removed & replaced by next 2 lines pingRev = Limits - pingDir PULSOUT PingServo, pingRev PAUSE BtwnPulses NEXT RETURN ' -----[ Subroutine - Polar_To_Cartesian ]------------------------------------ ' Calculates x and y (Cartesian coordinates) given distance and angle ' (polar coordinates). Polar_To_Cartesian: ' Calculate left/right component. 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 straight ahead component. 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 RETURN ' -----[ Subroutines - Single_Sweep ]----------------------------------------- ' Do one sweep, and find the closest distance measurement and the ' pulse value that points the servo in that direction. Single_Sweep: DO UNTIL pingDir >= LimitLeft GOSUB Sweep_Increment GOSUB Get_Ping_Cm IF distance < minDist THEN minDist = distance markDir = pingDir ENDIF LOOP RETURN ' -----[ Subroutine - Sweep_Increment ]--------------------------------------- ' Increment/decrement the position of the servo that directs the Ping))) ' rangefinder. When pingDir goes outside either LimitRight or LimitLeft, ' the sweep direction toggles. Sweep_Increment: ' Change sweepDir for adding/subtracting increment if at rotation limit. IF pingDir <= LimitRight THEN sweepDir = Positive ELSEIF pingDir >= LimitLeft THEN sweepDir = Negative ENDIF ' Add/subtract increment to/from pingDir. IF sweepDir = negative THEN pingDir = pingDir - sweepInc ELSEIF sweepDir = Positive THEN pingDir = pingDir + sweepInc ENDIF ' Send positioning pulse to Ping))) Mounting Bracket servo. ' PULSOUT PingServo, pingDir ' Forum: removed & replaced by next 2 lines pingRev = Limits - pingDir PULSOUT PingServo, pingRev RETURN ' -----[ Subroutines - Turn_Angle_Adjust ]------------------------------------ ' Adjusts required turn angle based on 7 mm offset of Ping))) rangefinder from ' Boe-Bot's turning axis. Turn_Angle_Adjust: ' Get the object's distance at its center. GOSUB Get_Ping_Cm ' Position servo & calculate angle from far-right in brads. angle = pingDir - 250 ** PingDirToAngle GOSUB Polar_To_Cartesian ' Add distance between Ping))) and center of Boe-Bot axis. y = y + PingAxleOffset ' Recalculate the turning angle with respect to Boe-Bot's turning axis. angle = x ATN y pulses = 64 - angle pSign = pulses.BIT15 RETURN
Thanks for your help!
Comments