e-techgarage.com — Larry's Workbench
Archive for the "C" Category

Collision Avoidance Algorithm

One of the major design goals for Rover has been autonomous behavior that avoids collisions.  Basically, turn him on, watch him go and NOT run into anything.  Here I will describe the main program and the Collision Avoidance (CAV) function.

The entire main program:

#define FIRST_STOP_DX    24

main ()

{

Rover_SetUp();                            // all of the initialization code, set up and enable the ISRs

TurretAngle(0);                           // initialize Rovers eyes to straight ahead

MsDelay(2000);                          // give Rover some time to settle

while (1)                                          // main loop

{

Rover_CAV ( FIRST_STOP_DX, 30 );      // mover Rover forward until he detects an obstacle (<24″) at 30% of full speed

MsDelay(2000);                                               // some time to think

Rover_Go ( ROVER_REVERSE, 15, 15 ); // backup a little

Wait4Motors();                                                 // wait for the motors to stop

Rover_Search();                                               // get distance for each of three angles:  -45,  0,  +45

if ( Obstacles[0] > Obstacles[2] ) Rover_Static_Turn ( -45, 50 ); // turn 45° away from the obstacle

else Rover_Static_Turn ( 45, 50 );

Wait4Motors();                                                 // wait for the motors to stop

MsDelay(1000);                                               // Rover is thinking again!

} // main loop

}

Now for the Collision Avoidance function:

void Rover_CAV ( int Stop_Dx, int Speed )

{      int distance,  DirFlag,  int i;

CurrentAngle = 0;                                  // current turret angle

DirFlag = 1;                                                // 1 = CW,     -1 = CCW

while (1)                                                      // stay in loop until obstacle is detected

{

Rover_Go ( ROVER_FORWARD, Speed, 15 ); // go forward for about 1 second (15 pulses)

while ( Motor_Status )                  // while motors are running

{

for ( i=-1;   i<=1;   i++ )       // for each scan angle

{       CurrentAngle = i*SEARCH_ANGLE*DirFlag;

TurretAngle(CurrentAngle);  // turn the turret

for ( SRF05ICdone=0; SRF05ICdone<5; )

/* The SRF05 is triggered once every 50msec.  Its output is a pulse proportional to the object distance.  The pulse is measured by the Input Capture system

of the Rabbit.  An interrupt is generated by Input Capture the end of each measurement of the SRF05 sonic sensor.  The variable SRF05ICdone is

incremented with each of the interrupts.  This for loop has the effect of causing a delay until 5 SARF05 readings have completed. */

{         if ( (distance=GetDistance()) < Stop_Dx ) // if obstacle

{         Rover_Stop(0);

return;

} // if obstacle

} // 50msec per count

} // for each scan angle

DirFlag *= -1;                          // reverse the scan direction

} // while motors are running

// stay in loop until obstacle is detected

} // Rover_CAV

Rover Library

Puck and I just completed a significant phase of Rover testing.

Working with the Rover

The attached library has some high level functions that the previous one does not have.  These functions essentially isolate the main program from requiring any knowledge of how the motors work.

The added functions are:

  • Rover_Go which has parameters of: Direction, Speed and Distance.  All four motors turn identically.
  • Rover_Static_Turn which has parameters of: Degrees of Rotation (+/- 180) and speed.
  • Rover_Stop which has one parameter: stop immediately or wait until all motors are no longer being driven and then stop.

The stop function actually drives the motor(s) in the opposite direction for two pulses.  Without this action the Rover will drift for about an  inch.

Download latest library here.

Initial Rover Software for the H-Bridge

The first project for this blog is a Wireless Rover using a Rabbit miniCore RCM5600W.  For more information on the car itself see Puck’s Workbench.  My primary tasks are:

  1. Write the low level driver code for developing the PWM signals which are used to drive the four H-bridges which drive the motors
  2. Design the H-bridge circuit.

The requirements for the software driver are:

  1. Use an ISR to create the PWM
  2. The period of the PWM pulse stream must be variable
  3. The duty cycle of each of the four pulse streams must be individually programmable
  4. The number of pulses for each motor must be individually programmable
  5. The direction of each motor must be individually programmable

The ISR I wrote does all of the above.  The resolution I chose is 1 millisecond and is based on Timer B being driven by Timer A1.  Timer B is set to divide by its full count of 1024.  The value for Timer A1 is calculated based on the CPU clock frequency.

This file is the initial ISR and test code: Rover.c.  (The file is saved as a .txt due to some browser/server problem with .C files.)  The code is well documented and should be fairly easy to follow.

TA7291SblkThe software was written based on using the Toshiba TA7291S H-Bridge.  The selection of this particular H-Bridge was quite pragmatic – I went to the Mouser web site and did a search for “H-bridge.”  The 7291 was one of the first ones listed with a reasonable price.  I looked up the specs on it and immediately saw that it was just what I was looking for ;-) .