Society of Robots - Robot Forum

General Misc => Robot Videos => Topic started by: mbateman on November 04, 2008, 01:12:24 PM

Title: My first attempt - platform ready
Post by: mbateman on November 04, 2008, 01:12:24 PM

Nuisance-3 V1.00
First robotic attempt
Matt Bateman - 11/4/08


[youtube]0rvanqqcCok[/youtube]

Goals:


Mechanical
Power
Electronics
I/O
R/C
PWM
Scheduler
Map

? ? ? ? ? ? ? ? ? ? ? . . . . . . ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? . . . . . . ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? . . . . . . . ? . ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? . ? . . . . . . . ? ? ? . ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? . ? . ? . ? . . . . . ? # ? o ? . ? ? ? ? ? ? ?
? ? ? ? ? . ? . . ? . . . . . . . . . . . ? . . ? . ? ? ? ? ?
? ? ? ? ? ? . ? o . . ? . . . . . . . ? # . . ? . ? ? ? ? ? ?
? ? ? ? . . ? . ? . . . . . . . . . . ? . o ? . ? . . ? ? ? ?
? ? ? ? ? . . ? # . . . . . . . . . . . # . . ? . . ? ? ? ? ?
? ? ? . . ? . . . . . . . . . . . . . . . o . . . ? . . ? ? ?
? ? ? ? ? . . . # o . . . . . . . . . . # . . . . . ? ? ? ? ?
? ? . . . . ? . ? # . . . . . # . . . . # o . . ? . . . . ? ?
? ? ? ? ? . . . . # . . . . . o . . . . . # . . . . ? ? ? ? ?
? ? . . . . . . . # . . . R R R R R . . . # # . . . . . . ? ?
? ? ? . . . . . . o . . . R R R R R . . . . # . . . . . ? ? ?
? ? . ? ? ? ? ? ? ? ? ? ? R R X R R ? ? ? ? ? ? ? ? ? ? . ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? R R R R R ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? # . . R R R R R . . . ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? . . . . # . . . . . . . . . ? . . ? ? ? ? ? ? ?
? ? ? ? ? . . . . . # # . . . . . . . . . o ? . . . ? ? ? ? ?
? ? ? ? . ? ? . . . # # . . . . . . . . . . . . ? ? . ? ? ? ?
? ? ? ? ? . . ? . . # . . . . . . . . . . . . ? . . ? ? ? ? ?
? ? ? ? ? . ? . . . . . # . . . . . . . . . . . ? . ? ? ? ? ?
? ? ? ? ? ? . ? ? . ? # # . . . . . . . ? . ? ? o ? ? ? ? ? ?
? ? ? ? ? ? ? ? . ? . ? . ? . . . ? . ? . ? . ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? . ? . . ? . . . . . . . ? . . ? . ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? . ? . . . ? . ? . . . ? . ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? . ? . ? . ? . ? . ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? . ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?


FSM

Lessons Learned
Next Steps
Title: Re: My first attempt - platform ready
Post by: mbateman on November 04, 2008, 01:39:45 PM
I forgot to list my very next step. I need to tune the turn and speed algorithms to get rid of the oscillations caused by changing location or direction faster than the map updates can keep up.
Title: Re: My first attempt - platform ready
Post by: Trumpkin on November 04, 2008, 02:04:17 PM
NICE JOB!
Title: Re: My first attempt - platform ready
Post by: Webbot on November 04, 2008, 04:42:45 PM
Excellent - have seen a purple haired Gonk for a while.

So if the map is 32x32  x 3inches then it looks from the video that the robot must be going off the map. What happens in that case.

You don't mention encoders - so how do you calculate your current position?

Good job

Title: Re: My first attempt - platform ready
Post by: mbateman on November 04, 2008, 04:47:11 PM
The map is always relative to the robot. i.e.: the robot is in the center of the map at all times. It is really more of a radar screen than a map. Sensor inputs are plotted on the map and then fade away over about a second unless updated by a new sensor input. So it shows the immediate area around the robot. That is why any state that causes it to stop and turn quickly forces it back to the learning state so the map has time to catch up.
Title: Re: My first attempt - platform ready
Post by: Admin on November 06, 2008, 02:37:26 AM
Nice! Reminds me of my old HyperSquirrel and Fuzzy robots back in the day :)

Got closeup pics and code to post? I put your bot on the Axon examples page.

Suggestion: double up each servo scanner with another Sharp IR to double your map generation speed.
Title: Re: My first attempt - platform ready
Post by: Razor Concepts on November 06, 2008, 11:13:06 AM
Please post the code! I'm trying to figure out how to read the outputs a receiver puts out, and it looks like you've done it sucessfully.
Title: Re: My first attempt - platform ready
Post by: mbateman on November 06, 2008, 12:52:58 PM
Here is most of the R/C code. Some items are in my hardware.c file, but the hard parts are all here. Sorry about the formatting. The code output here seems to strip all the tabs. ;-(

The rcDoUpdate() command will need to be run on a regular basis to convert the pulse times into useful data. I did not do that in the interrupt routine since it takes a bit of time and is not needed for every pulse. You just need to do it before using the data.

Also, set the PCMSK2 to 0x00 during any servo pulses and then back on when done. If you don't, then this interrupt routine will take enough time away from your servo command that it will change the pulse out and make your servos jitter. I defined my own servo command...

#define myServo(port,number,position)   PCMSK2=0;PORT_ON(port,number); delay_cycles(position); PORT_OFF(port,number);PCMSK2=rcPinMask


Code: [Select]
#define rcVer 1
#define rcRev 0

#define rcMaxChannels 6 // Maximum R/C channels
#define RC_NO_SIGNAL -127 // Value to use if no signal is present
#define rcSignals2BeValid 8 // Must see at least this many pulses to consider radio to be on
#define rcMaxDroppedSignals 3 // Must lose this many pulses to consider radio off

// The following min/max are used to filter out noise and interference.
#define rcBasePeriodMin 21800 // Min base period in uS
#define rcBasePeriodMax 22200 // Max base period in uS
#define rcPulseTimeMin 950 // Min pulse period in uS
#define rcPulseTimeMax 2050 // Max base period in uS

#define rcPinMask 0x3F // Mask to turn on all R/C pins.

// Connect R/C inputs to Bank K 0-7 (input pins 8-15)
// R/C channel 1 -> K0
// R/C channel 2 -> K1
// R/C channel 3 -> K2
// R/C channel 4 -> K3
// R/C channel 5 -> K4
// R/C channel 6 -> K5
// R/C channel 7 -> K6
// R/C channel 8 -> K7



// Build a structure to hold the data for each pin
struct  {
unsigned long int startTime;
unsigned long int pulseTime;
unsigned long int basePeriod;
  signed      int signalsUntilValid;
  signed   int pct; // Value range from -100 to 100
} rcPin[rcMaxChannels];

// Global variable that can be used to determine if the radio is on or off.
// #define of OFF and ON in main.h
// #define ON 1
// #define OFF 0
int rcState=OFF;


signed int rcGetChannel(unsigned int channel) {
/***************************************************/
/* Get the current value of the requested channel. */
/* Returns percent as -100 to 100                  */
/***************************************************/
return(rcPin[channel-1].pct);
}

int rcIsOn(void) {
/******************************/
/* Returns state of R/C radio */
/******************************/
return rcState;
}


unsigned long int rcGetDiff(unsigned long int now, unsigned long int last) {
/*************************************************/
/* Get the time difference between now and last  */
/* Must divide by 2 since prescale only /8 and   */
/* CPU is 16Mz. getTimeDiff defined elsewhere... */
/* #define getTimeDiff(now,last) ((last>now)?(65535-last+now):(now-last)) */
/*************************************************/
return (getTimeDiff(now,last)/2);
}

ISR (PCINT2_vect){
/********************************/
/* Handle pin changes on PORT K */
/* via interrupts.              */
/********************************/
u08 pulseDefRise,pulseDefFall;
static u08 prevState; // Holds the previous state of K7-0
u08 currState=PINK; // Get current state of K7-0
u08 mask;
unsigned long int now=TCNT5; // Timer5. Rolls over at 65535


pulseDefRise = (~prevState) & ( currState); // Rising edges
pulseDefFall = ( prevState) & (~currState); // Falling edges

for (int pin=0;pin<rcMaxChannels;pin++) {
mask=0x01<<pin;
if(pulseDefRise & mask){ // Rising edge
/* Rising edge to rising edge = base period */
rcPin[pin].basePeriod=rcGetDiff(now,rcPin[pin].startTime); // Calculate base period
rcPin[pin].startTime=now;
} else if(pulseDefFall & mask){ // Falling edge
/* Rising edge to falling edge = pulse time */
rcPin[pin].pulseTime=rcGetDiff(now,rcPin[pin].startTime); // Calculate pulse time
/* Determine if the pulse is good */
if (rcPin[pin].basePeriod > rcBasePeriodMin
&& rcPin[pin].basePeriod < rcBasePeriodMax
&& rcPin[pin].pulseTime > rcPulseTimeMin
&& rcPin[pin].pulseTime < rcPulseTimeMax) {
// Possible good signal
if (rcPin[pin].signalsUntilValid > -rcMaxDroppedSignals) {
rcPin[pin].signalsUntilValid--;
if (rcPin[pin].signalsUntilValid==0) {
// Saw enough to be good
rcPin[pin].signalsUntilValid=-rcMaxDroppedSignals;
}
}
} else {
// Possible lost signal
if (rcPin[pin].signalsUntilValid < rcSignals2BeValid) {
rcPin[pin].signalsUntilValid++;
if (rcPin[pin].signalsUntilValid==0) {
// Lost too many in a row
rcPin[pin].signalsUntilValid=rcSignals2BeValid;
}
}
}
}
}
prevState=currState;
}

void rcDoUpdate(void) {
/***************************************************/
/* Sanity check and convert R/C inputs.            */
/* This process should be run on a regular basis   */
/* based on the update freqency required for       */
/* reading the R/C values.                         */
/***************************************************/
int tmpState=OFF;
for (int pin=0;pin<rcMaxChannels;pin++) {
if (rcPin[pin].signalsUntilValid<0) {
tmpState=ON;
}
if (rcPin[pin].signalsUntilValid==-rcMaxDroppedSignals) {
// Last pulse was valid so convert it to a percentage
rcPin[pin].pct=rcReceiverConvert(rcPin[pin].pulseTime);
} else {
// Last pulse may not be valid so don't use
rcPin[pin].pct=RC_NO_SIGNAL;
}
}

if (tmpState) {
LED_on();
} else {
LED_off();
}
rcState=tmpState;
}

void rcInit(void) {
/*****************************/
/* Set up interrupts for R/C */
/*****************************/
rprintf(" R/C:      \t%d",rcVer); rprintf(".%d\t",rcRev);
// Clear all channel info
for (int pin=0;pin<rcMaxChannels;pin++) {
rcPin[pin].pct=RC_NO_SIGNAL;
rcPin[pin].signalsUntilValid=rcSignals2BeValid;
}
// Enable PCINT2
PCICR=0x04;
// Turn on for 6 channels
PCMSK2=rcPinMask;
// 00 A off, toggle on compare
// 00 B on, toggle on compare
// 00 C on, toggle on compare
// 00 Low part of WGM: None
TCCR5A=0x00;
// 0 No input noise cancelling
// 0 Input edge select does not matter
// 0 Not used
// 00 High part of WGM: None
// 010 Prescale 8
TCCR5B=0x02;
// Clear TCNT
TCNT5H=0x00;
TCNT5L=0x00;
// Enable timer5 overflow interrupt
// TIMSK5=0x01;
// Schedule update
schedAdd(rcDoUpdate,timerRcDoUpdate);
// Done
rprintf("done\r\n");
}
Title: Re: My first attempt - platform ready
Post by: mbateman on November 06, 2008, 12:57:04 PM
Hah, the code looks just fine once posted. Just the preview has the tabs gone.
Title: Re: My first attempt - platform ready
Post by: Rebelgium on November 06, 2008, 01:33:49 PM
Excellent post, great robot.
I really enjoyed reading it, the "lessons learned" part was helpfull.
I'm actually prototyping with a Hitec HS422 right now, and I was just wondering whe the F it didn't turn the whole 180°...Thanks for the info.

Quote
a slight misalignment causing a left turn when told to go straight. I was able to correct the alignment with shims.
What's a shim?

Title: Re: My first attempt - platform ready
Post by: Trumpkin on November 06, 2008, 01:52:33 PM
Quote
What's a shim?
http://en.wikipedia.org/wiki/Shim_(engineering)
Title: Re: My first attempt - platform ready
Post by: ryan on November 09, 2008, 08:00:27 PM
Nice robot..congrats
Title: Re: My first attempt - platform ready
Post by: Dscrimager on December 06, 2008, 12:36:26 PM
Fantastic, it's pretty close to what I am shooting for with my shiny new AXON. I really like the 'radar screen' world map approach... let no good idea go unused!

Doug
Title: Re: My first attempt - platform ready
Post by: cooldog on December 06, 2008, 04:06:49 PM

  • Detect stairs - I have yet to find a good way to determine when it is about to plummet down the stairs or any other abrupt edge like that

irobot rummba uses ir rangefinders pointing at the ground to detect stairs
Title: Re: My first attempt - platform ready
Post by: SeagullOne on December 10, 2008, 05:51:15 PM
Extremely impressive Robot, mbateman! Very clever use of code and your 'radar' screen approach! Nicely done indeed!