PDA

View Full Version : scan for objects code help needed?



voodoo
04-17-2013, 10:51 PM
Hi forum, I have been working on some software in c using mplab. I am trying to turn my robot 360º on the spot to scan the surroundings & then find the best direction to start off when it starts up. Ie, the least closest objects or best position itself to start a maze. I am using a sw timer to time the spin so its exact 360º & using a quick oppisite direction of the motors to break it to stop dead. I have managed to make it find the closest object & turns to face it. The timer counts up to 900 to make it spin. I want to make an array & have the array [18] to increase by one each time the timer counts to 50 & store the adc results in each varable of the array. But I'm not quite sure how to go about it exactly. My code in short so far:

int highADC;
int a;
int Angle;
If (mode ==0)
{
If (timer (rotationTimer) //check timer
{
rotationTimer = 0.001; //set timer
a++;
If (highADC < readADC (ch8)) //store highest number
{
highADC = readADC (ch8);
Angle = a; //position on timer
}
Turn motors; // I just put in short hand to save space

If (a >= 900) //when a = 900 move to next mode. Ie stop
mode = 1;
}
& so on after that I use the timer to count up to the resuult Angle thus the robot finds the closest object. Simple. Well any advice to how to increase an array varable by one every 50 timer cycles & store each adc result? I hope you can understand my code. Maybe use a for loop?

jwatte
04-18-2013, 12:27 AM
You probably want to store the "closest" position within each sub-range of 50, right?
A way of doing this is to initialize the array to "infinitely far" and then use a minimizing function.
Something like:



unsigned int distance[18];

void func(void) {
for (int i = 0; i != 18; ++i) {
distance[i] = 65535; // max unsigned int on Atmega
}
start_spin();
unsigned short startTime = read_timer();
while (true) {
unsigned short curTime = read_timer() - startTime;
if (curTime >= 900) {
break;
}
unsigned short d = read_distance();
unsigned char ix = curTime / 50;
if (distance[ix] > d) {
distance[ix] = d;
}
}
stop_spin();
}


Now, the "distance" array will contain the minimum distance in each of the 18 general directions.

However, I would not rely on timing to "exactly" turn 360 degrees. Depending on battery freshness, interrupt load, and phase of the moon, your timing will end up being slightly too low, or slightly too high. Much better to use encoders on the wheels if possible, or something like an I2C compass.

CasperH
04-18-2013, 01:05 PM
However, I would not rely on timing to "exactly" turn 360 degrees. Depending on battery freshness, interrupt load, and phase of the moon, your timing will end up being slightly too low, or slightly too high. Much better to use encoders on the wheels if possible, or something like an I2C compass.

Good suggestion, to get better accuracy I would go for something like:


Use an absolute encoder (make it easy for yourself).
Read the angle.
Map the distance of that angle in your array, link it to index.
Find the lowest value in the array.
Turn there around the center of the vehicle (if possible) to angle found at no4.

Some food for thought..


How much angle accuracy are you going for i.e. how many variables for the 360 degrees in your array?
How do you deal with odometric inaccuracy, for example you find your robots best direction is at 50 degrees, but you are at 120. You will have to rotate 70 degrees (exactly?). Do you scan again at that moment after turning or continuously?

What robot platform are you using?

You mention the best direction to move to, will this be the closest object or the furthest away?

voodoo
04-18-2013, 07:44 PM
Thanks for the replies guys. Yes jwatte I want to scan each sub range of 50, so the timer steps 900 positions & counts through an array of 18 thus 50 ever varable of the array. The timer is a seperate header file I wrote, so I just simply write what ever timer I want. The code is handy that you wrote, exept I address my timer different.

Thank you Casper, I do a complete scan 360º then sw breakes. Stop then from the information of the array I want to spin the robot to the best direction. Having anarray I was hoping to be able to make instructions for different situations. Ie a gap or just objects around the robot field of view.

jwatte
04-18-2013, 08:47 PM
he code is handy that you wrote, exept I address my timer different.

Think of it as pseudo-code and adapt it to actually work in your code. The main idea is how to calculate the "best bucket" among your 18 buckets.

voodoo
04-18-2013, 10:27 PM
Thanks again Jwatte! Your right I can use the code as needed. I can use timing as I have a pololu voltage regulator that gives a constant voltage & amps even when the battery gets low. An adc on the mcu checks when the battery is low also.