Another Project using the Pololu beacon

In this project I use a home brewed laser sensor coupled with a Ping))) as sort of a poor man’s LIDAR. But I couple it with a Pololu beacon so the robot can find its way home. The red laser and the beacon’s IR didn’t interfere which was something I was worried about.

Hello.

That is a very nice project. Thank you for sharing it with us. Keep us the good work!

By the way, did you use any other Pololu parts in your project, and do you have your build documented somewhere?

-Derrill

Thanks. The beacon was the only Pololu part for this build, but I have two other projects which I could write up. One uses wixels, the other a Baby Orangutan and the Pololu mini-IMU.

For technical details. I used an existing design for the laser sensor described here: forums.parallax.com/showthread.p … r-Bulk-Buy So that’s not my own design, but it was a scratch build.

The Boe-bot, gripper, and Ping))) sensor are all stock Parallax parts. The only other secret sauce was the coding which took about five hours. I used a BS2 and PBasic which is probably considered obsolete, but it’s a no drama programming environment and I find it easy to knock out projects. Here’s the code if anyone wants it.

' ==============================================================================
'
'   File...... FetchTargetAndFindBeacon.BS2
'   Purpose... Find a target using the Ping))) and laser, then returns to
'              the beacon
'   Authors... Martin Heermance.
'   E-mail.... mheermance@gmail.com
'   Started... 2014 September 6th
'   Updated... 2014 September 7th
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' ==============================================================================

' ------------------------------------------------------------------------------
' Program Description
' ------------------------------------------------------------------------------
' A program to locate a target using a laser, then return to the Pololu beacon

' ------------------------------------------------------------------------------
' Revision History
' ------------------------------------------------------------------------------
' 2014-09-XX Initial creation and ongoing development.

' ------------------------------------------------------------------------------
' I/O Definitions
' ------------------------------------------------------------------------------

Laser           PIN      0                    ' Laser input
BLeft           PIN      6                    ' Beacon to left indicator
BBack           PIN      7                    ' Beacon in back indicator
BRght           PIN      8                    ' Beacon to right indicator
BFront          PIN      9                    ' Beacon in front indicator
Buzzer          PIN     10                    ' pin for output sound
RMotor          PIN     12                    ' Pin for right servo
LMotor          PIN     13                    ' Pin for left servo
Gripper         PIN     14                    ' Pin for gripper servo
Ping            PIN     15                    ' Pin for PING))) Sensor

' ------------------------------------------------------------------------------
' Constants
' ------------------------------------------------------------------------------

'--------[Calibration Constants, must be adjusted for your specific robot]------
GripperOpened   CON     500                   ' PULSOUT pulse width to open gripper servo
GripperClosed   CON     960                   ' PULSOUT pulse width to close gripper servo

' These values need tweaking for each robot's servos.
SpeedF75L       CON     840  ' Fast forward left
SpeedF50L       CON     808  ' Med  forward left
SpeedF25L       CON     775  ' Slow forward left
Speed000L       CON     750  ' stop left
SpeedR25L       CON     710  ' slow reverse left
SpeedR50L       CON     690  ' med reverse left
SpeedR75L       CON     650  ' fast reverse left

SpeedF75R       CON     650  ' Fast forward right
SpeedF50R       CON     690  ' med forward right
SpeedF25R       CON     720  ' slow forward right
Speed000R       CON     750  ' Stop right
SpeedR25R       CON     775  ' slow reverse right
SpeedR50R       CON     810  ' med reverse right
SpeedR75R       CON     850  ' Fast reverse right

'---------[Other Global Constants]----------------------------------------------

NULL            CON     750                   ' Pulse width for 1.5ms stop pulse.
Trigger         CON     5                     ' trigger pulse = 10 uS
Scale           CON     $200                  ' raw x 2.00 = uS

RawToIn         CON     889                   ' 1 / 73.746 (with **)

IsHigh          CON     1                     ' for PULSOUT
IsLow           CON     0

Success         CON     0                     ' Constant for zero success
ErrorBeaconLost CON     -1                    ' Constant for lost on move
ErrorTooClose   CON     -2                    ' Constant for farther than max

RIGHT           CON     0                     ' Subscripts into arrays.
LEFT            CON     1
FRONT           CON     2
BACK            CON     3

COM_SPEED       CON     84                    ' 9600 baudnon-inverted.

' ------------------------------------------------------------------------------
' Variables - for simplicty I use exactly the same variables in all modules.
' ------------------------------------------------------------------------------

' General purpose volatile variables which are modified by subroutines or tasks
ACC             VAR     Word

' Loop index variables and for argument passing.
X               VAR     Word
Y               VAR     Word
Z               VAR     Word

' DirReads is a nibble array
DirReads        VAR     Nib(4)

' State variables which are modified to reflect changes of robot state.
RSpeed         VAR      Word   ' Holds current r motor pulse
LSpeed         VAR      Word   ' Holds current l motor pulse
GripState      VAR      Word   ' Holds current gripper pulse

' ------------------------------------------------------------------------------
' Initialization
' ------------------------------------------------------------------------------

' ------------------------------------------------------------------------------
' Program Code
' ------------------------------------------------------------------------------

  ' Pause at start of program to let user set down robot.
  FREQOUT Buzzer, 1000, 2500

  GripState = GripperOpened
  GOSUB Halt              ' stop robot

  GOSUB FindTarget
  GOSUB Fetch

  GripState = GripperClosed
  GOSUB Halt

  GOSUB FindBeacon
  END

' ------------------------------------------------------------------------------
' Subroutines
' ------------------------------------------------------------------------------

' slowly rotate until the laser target finds target
FindTarget:

    RSpeed = SpeedF25R
    LSpeed = SpeedR25L
  DO
    ' Each iteration refresh the servos
    GOSUB PulseServos
    IF (Laser = IsLow)  THEN
      GOSUB Halt
      FREQOUT Buzzer, 1000, 2500
      RETURN
    ENDIF
  LOOP

' moves towards the target and stops when it is in range
Fetch:
  Y = 0
  DO
    Y = Y + 1
    ' Every so often check that we still see the target
    ' If not then turn TO face it
    IF (Y > 35 AND Laser = IsHigh)  THEN
      GOSUB FindTarget
      Y = 0
    ENDIF

    ' slowly move forward to the desired distance to the target
    RSpeed = SpeedF50R
    LSpeed = SpeedF50L
    GOSUB PulseServos

    ' Exit if we're close to the target
    GOSUB PingDistance
    IF (X < 3)  THEN
      GOSUB Halt
      RETURN
    ENDIF
  LOOP

' PingDistance - reads the distance to the target.
' Inputs:
' Outputs:
'   X - distance in inches.
PingDistance:
  Ping = IsLow                                ' make trigger 0-1-0
  PULSOUT Ping, Trigger                       ' activate sensor
  PULSIN  Ping, IsHigh, X                     ' measure echo pulse
  X = X */ Scale                              ' convert to uS
  X = X / 2                                   ' remove return trip
  X = X ** RawToIn                            ' convert to inches
  RETURN

' Turn the robot on its axis by the amount in signed byte Arg at speed Veloc.
' Inputs:
'   Arg - number of brads to turn. > 0 turns left; Arg < 0 turns right.
'   Veloc - peak speed where 0 is stop and 15 is fast.
' Outputs:
'   X - 0 success, -1 beacon lost, -2 closer than min
Turn:
  RETURN

' Stop moving
Halt:
  RSpeed = Speed000R
  LSpeed = Speed000L

' Called to refresh the servos.
PulseServos:
  PULSOUT RMotor, RSpeed
  PULSOUT LMotor, LSpeed
  PULSOUT Gripper, GripState
  PAUSE 20
  RETURN

' ReadBeacon - scans the beacon pins, removes spurious noise and returns value.
' Inputs:
'   none
' Outputs:
'   ACC - most common direction
'   Z - number of occurances
ReadBeacon:
  FOR Y = RIGHT TO BACK
    DirReads(Y) = 0
  NEXT

  FOR Y = 0 TO 6
    IF BFront = IsLow THEN
      DirReads(Front) = DirReads(Front) + 1
    ENDIF
    IF BRght = IsLow THEN
      DirReads(Right) = DirReads(Right) + 1
    ENDIF
    IF BLeft = IsLow THEN
      DirReads(Left) = DirReads(Left) + 1
    ENDIF
    IF BBack = IsLow THEN
      DirReads(BACK) = DirReads(BACK) +  1
    ENDIF
  NEXT

  ' Have a bias towards LEFT to initiate beacon search
  ACC = LEFT
  Z = DirReads(LEFT)
  FOR Y = RIGHT TO BACK
    ' If this direction is more common than current max, make it max
    IF DirReads(Y) > Z THEN
      ACC = Y
      Z = DirReads(Y)
    ENDIF
  NEXT
  RETURN

' Find the beacon, althouh at the present no exit condition is specified
FindBeacon:
  ' slowly rotate until the beacon locater spots its target
  RSpeed = SpeedF25R
  LSpeed = SpeedR25L
  DO
    ' Each iteration refresh the servos
    GOSUB PulseServos
    GOSUB ReadBeacon
    IF (ACC = Back)  THEN
      ' quickly do a 180
      RSpeed = SpeedR75R
      LSpeed = SpeedF75L
      Y = 40
    ELSEIF (ACC = Right)  THEN
      ' rotate until the beacon is front
      RSpeed = SpeedR50R
      LSpeed = SpeedF50L
      Y = 20
    ELSEIF (ACC = Left)  THEN
      ' rotate until the beacon is in front
      RSpeed = SpeedF50R
      LSpeed = SpeedR50L
      Y = 20
    ELSEIF (ACC = Front)  THEN
      ' Move towards beacon
      RSpeed = SpeedF75R
      LSpeed = SpeedF75L
      Y = 1
    ENDIF
    DO UNTIL Y = 0
      GOSUB PulseServos
      Y = Y - 1
    LOOP
  LOOP

I just remembered that I’m using the Pololu QTR-8RC reflectance sensor array on this robot as well. Here’s a video of an earlier version of this project using the line sensor to remove the target from a ring.

Thank you adding for that video. I see you posted about another one of your robots on our forum. We love seeing how our products are used in these great robots!

-Derrill