Robomagellan 2012 Build Diary - Day 8

You can find the beginning of this project blog here: http://buildsmartrobots.ning.com/profiles/blogs/robomagellan-2012-b...

My first week on the project and I am already behind.  I was doing some really exciting work for my real job and putting in some serious hours.  I did get a few hours here and their to work on the RoboMagellan robot and I worked on it all day Saturday.

Through the week I was able to wire up the 6x6 chassis and get the speed control and servos installed.  I also built a tower on the robot to mount the compass as high as possible.

The Minds-i 6x6 Rover kit is an amazing robot platform.  All 6 wheels are driven through 2 gearboxes by 2 motors.  The front and back wheels pivot for steering.  The chassis is solid but has just enough give to twist and keep all 6 wheels on the ground.  The springs on the shocks are adjustable.  I set the shock springs to max tension which allows the robot to hold a netbook and batteries without sagging.

Dual Motor Drive - Oh Yea!!!!!

One servo on each side for steering.  Adjusting the steering takes some patients, I am still trying to get it right.

Checkout the video in the comments below to see the robot in action.  It drove over a 4 inch concrete edge like the edge was not even there.  If you listen to the audio in the video, you will here my surprise.

On top of the tall tower is the compass.  The compass is mounted high to avoid magnetic interference from the motors.

This week I also ordered the ultrasonic ranging modules for the robot.  After significant debate, I decided to go with the MaxBotix MB1000's ( http://www.maxbotix.com/products/MB1000.htm ).  Basically it boiled down to cost.  I needed 6 of these sensors.  I really could not afford more than $26.95 (on sale at http://www.pololu.com ).  I really wanted the MB1200 because I think it is the correct sensor for the job, I just could not afford $250.00 in ultrasonic range finders.  By going with the MB1000 I was able to buy all 6 for only $162.00 and after adding the LS20031 GPS receiver module my Pololu bill was less than $212.  Robotics is tough when you are saving for school.

After spending a few hours pouring over the MaxBotix website (http://www.maxbotix.com/)I have come to the conclusion that they make a really good sensor.  The documentation is clear and easy to understand, and their sensor have a ton of great features.  I know some of the other RoboMagellan robots use them and everyone I talked to who have used the sensors had only good things to say about MaxBotix.  When I get the sensors I plan on running some experiments with them and posting the results.

The MaxBotix ultrasonic range modules come in five different beam profiles (EZ0-EZ4) shown below.

The Ultrasonic range modules are the only form of obstruction detection on the robot.  I had two design goals in mind; long range and wide divergence.  My design calls for the beam patterns to overlap, so the beam pattern had to be wide to get the complete 120 degrees I wanted using only 5 sensors.  I need the distance because this is a fast robot.  The further away I can detect an obstruction, the better chance I have of avoiding it.  If you notice in the beam patter charts above, for an ultrasonic sensor, range is dependent on object size.  The bigger an object the farther away you can detect it.  Graphs A. B, and C represent detection patterns for object of 3 different sizes; 0.25 inches, 1 inch, and 3.5 inches.   I chose to use the 0.25 inch graph (A) for my calculations.  This is a worst case, and natural obstruction include branches that may be only 0.25 inches across.  According to the beam pattern plots above, the MB1000 has the best detection range for a 0.25 inch object ( 82 inches or approximately 7 feet ).  This is going to be very tight for a robot as fast as the 6x6 but I always have the option of slowing the robot down.

 

Last Saturday I spent 6 hours laying out a new board for the RoboMagellan Robot.  It uses three MSP430G2553's to do GPS/compass navigation, motor control, and high level decision making for the robot.  Everything except Computer Vision is done using three 16bit microcontrollers connected together using i2c.

 

 

 

 

 

Views: 524

Tags: emgrobotics, mb1000, minds-i, msp430g2553, robomagellan, ultrasonic

Comment by eric gregori on July 4, 2012 at 3:32pm

Comment by eric gregori on July 5, 2012 at 5:26am

I2C communications

Based on a 100ms "tick".

Executive is Master, GPS and motor are slaves.

In "driving to waypoint" mode, every 100ms the master:

1) Sends steering angle(1 byte) and velocity(1 byte) to motor

2) Receives state flags from motor (1 byte)

3) Sends waypoint to GPS (8 bytes)

4) Receives bearing from GPS (1 bytes)  2 degree accuracy should be good enough

If 100ms is too slow of a update rate (I doubt it) I can change the "tick" rate to 50.

When in "visually tracking cone mode" steps 3 and 4 are removed.

Comment by eric gregori on July 5, 2012 at 5:38am

The bearing between two points (when the points are close, no great circle) is simply:

atan2( long1-long2, lat1-lat2)*180/pi    degrees

180/pi = 57.295779513082320876798154814105

the GPS microcontroller runs the above equation and reads the compass bearing from the digital compass.  The two values are pumped into the equation below to calculate steering offset angle.

steering offset angle = K*(GPS bearing - compass bearing) 

Where K is a gain.  The higher the gain, the more aggressive the robot maintains bearing (most likely oscillating).

Comment by eric gregori on July 6, 2012 at 5:49am

"after which the pulse width pin (PW) is set high. When a target is detected the PW pin is pulled low. The PW pin is high for up to 37.5mS if no target is detected."  http://www.maxbotix.com/documents/MB1000_Datasheet.pdf

Positive edge = start counting, Negative edge stop counting

Pulse width = (147uS/inch)

The MSP430G2553 will be running at 16Mhz (.065us/count).  MCLK = 16Mhz, SMCLK = 16Mhz.  Using a 

/8, the timer runs at 2Mhz or 0.5us/count.  Max pulse width is 37500us or 75000 counts.

9465 count overrun = 4732us = 32 inches

So max detectable distance will be approximately 17 feet.

MSP430G Timer A

Mode = continuous

CAP = 1

interrupt on capture

For 5 sensors, 10 interrupts every ~100ms

A state machine in the capture interrupt handler switches between capture on rising and capture on falling.

It simply copies the capture data to memory (this may be doable using DMA).

The application code reads the data and uses it to calculate distance, this minimizes the amount of time spent in ISR. 

Comment by eric gregori on July 6, 2012 at 2:18pm

Comment by eric gregori on July 7, 2012 at 11:26am

Comment by eric gregori on July 8, 2012 at 3:04am

The devil is in the details.

On the MSP430G2553, not all timer pins can be used for INPUT capture;

Pin 7, TA0.0 - output compare only

Pin 14, TA0.1 - output compare only

Pin 19, TA0.1 - ouput compare only

Comment by eric gregori on July 10, 2012 at 11:07am

This morning at about 5AM I got the ultrasonic sensor drivers working (both analog and pwm in).

// 3 Ultrasonic sensors are connected to input captures on timer 1
// 3 Ultrasonic sensors are connected to analog inputs A3,4,5
// Start timming on rising edge, stop on falling edge
// 147us / inch 37.5ms max
void RoboMagellan_InitUltrasound(void)
{
// Init Timer 1 ultrasonic sensors
TimerState = 0;
TA1CCTL0 = 0xC910; // BothEdges, CCI0A, SCS, CAP, IE,
TA1CCTL1 = 0xD910; // BothEdges, CCI1B, SCS, CAP, IE,
TA1CCTL2 = 0xC910; // BothEdges, CCI2A, SCS, CAP, IE,
TA1CTL = 0x02e2; // SMCLK(16Mhz), /8, continuous, interrupts enabled

AD_Data_Index = 0;
// Init Analog ultrasonic sensors
ADC10CTL1 = INCH_5 + CONSEQ_3; // A5-A0, repeat multi channel, ADC10SC bit=start, ADC10OSC
// vcc/gnd, 16 sample/hold, continuous, ADCON
ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON; // VR+=VCC, VR-=GND, continuous, + ADC10IE;
ADC10DTC0 = ADC10CT;
ADC10DTC1 = 6;
ADC10CTL0 &= ~ENC;
while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
ADC10SA = (unsigned int)AD_Data;
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer1_A0 (void)
{
if((TimerState & 0x01) == 0)
{
RisingEdge[0] = TA1CCR0;
TimerState |= 0x01;
}
else
{
PulseTimes[0] = TA1CCR0 - RisingEdge[0];
TimerState &= ~0x01;
}
}

#pragma vector=TIMER1_A1_VECTOR
__interrupt void Timer1_A1 (void)
{
volatile unsigned short ta1iv;

ta1iv = TA1IV; // Reading TA1IV clears it

if( ta1iv == TA1IV_TACCR1 )
{
if((TimerState & 0x02) == 0)
{
RisingEdge[1] = TA1CCR1;
TimerState |= 0x02;
}
else
{
PulseTimes[1] = TA1CCR1 - RisingEdge[1];
TimerState &= ~0x02;
}
}
else if( ta1iv == TA1IV_TACCR2 )
{
if((TimerState & 0x04) == 0)
{
RisingEdge[2] = TA1CCR2;
TimerState |= 0x04;
}
else
{
PulseTimes[2] = TA1CCR2 - RisingEdge[2];
TimerState &= ~0x04;
}
}
}

Comment

You need to be a member of buildsmartrobots to add comments!

Join buildsmartrobots

EMGRobotics

© 2013   Created by eric gregori.

Badges  |  Report an Issue  |  Terms of Service