Я работаю над роботом, это часть летнего семинара по робототехнике в нашем колледже. Мы используем микроконтроллеры C-STAMP от A-WIT. Я смог заставить его двигаться, повернуть налево, повернуть направо, двигаться назад. Мне даже удалось заставить это идти по черной ленте, используя датчик контраста.
Я посылаю робота под углом 30-45 градусов к черной ленте на столе, и он выравнивается и начинает двигаться по черной ленте. Он немного дергается, возможно, из-за моей логики программирования, приведенной ниже, он выполняет цикл while и постоянно проверяет операторы if, поэтому в конечном итоге он пытается поворачиваться влево и вправо каждые несколько миллисекунд, что объясняет часть рывков. Но все в порядке, работает, не так гладко, как я хочу, чтобы это работало, но это работает! Проблема в том, что я не могу заставить своего робота идти по прямоугольному пути из черной ленты. Как только он достигает угла черной ленты, он продолжает идти прямо, вместо того, чтобы поворачивать налево или направо.
Мои 2 датчика расположены прямо под роботом, рядом с передним колесом, почти на уровне пола. Он имеет значение «index» в диапазоне от 0 до 8. Восемь - самый яркий контраст, а ноль - самый темный контраст. Поэтому, когда робот перемещается в зону черной ленты, значение индекса падает, и на основании этого у меня есть оператор if, указывающий роботу повернуть налево или направо.
Вот моя попытка. Чтобы избежать путаницы, я не опубликовал весь исходный код, а только логическую часть, отвечающую за движение моего робота по черной ленте.
while(1) {
// don't worry about these.
// 10 and 9 represent Sensor's PIN location on the motherboard
V = ANALOGIN(10, 1, 0, 0, 0);
V2 = ANALOGIN(9, 1, 0, 0, 0);
// i got this "formula" from the example in my Manual.
// V stands for voltage of the sensor.
// it gives me the index value of the sensor. 0 = darkest, 8 = lightest.
index = ((-(V - 5) / 5) * 8 + 0.5);
index2 = ((-(V2 - 5) / 5) * 8 + 0.5);
// i've tweaked the position of the sensors so index > 7 is just right number.
// the robot will move anywhere on the table just fine with index > 7.
// as soon as it drops to or below 7 (i.e. finds black tape), the robot will
// either turn left or right and then go forward.
// lp & rp represent left-wheel pin and right-wheel pin, 1 means run forever.
// if i change it from 1 to 100, it will go forward for 100ms.
if (index > 7 && index2 > 7)
goForward(lp, rp, 1);
if (index <= 7) {
turnLeft(lp, rp, 1);
goForward(lp, rp, 1);
// this is the tricky part. i've added this code last minute
// trying to make my robot turn, but i didn't work.
if (index > 4) {
turnLeft(lp, rp, 1);
goForward(lp, rp, 1);
}
}
else if (index2 <= 7) {
turnRight(lp, rp, 1);
goForward(lp, rp, 1);
// this is also the last minute addition. it's same code as above
// but it's for the 2nd sensor.
if (index2 > 4) {
turnRight(lp, rp, 1);
goForward(lp, rp, 1);
}
}
}
Я провел весь день, пытаясь понять это. Я почти исчерпал все возможности. Запрашивать решение для stackoverflow - это мой самый последний вариант.
Заранее спасибо!
Если у вас есть какие-либо вопросы по поводу кода, дайте мне знать, но комментарии должны быть понятны.
Это моя функция goForward, если кому-то интересно:
void goForward(BYTE lp, BYTE rp, WORD t)
{
WORD i;
for(i = 0; i < t; i = i + 1){
PULSOUT(lp, 400, 1, 1);
PULSOUT(rp, 800, 1, 1);
PAUSE(17);
}
}
ОБНОВЛЕНИЕ: Вот что я придумал до сих пор. Я удалил все свои операторы if, которые я разместил ранее, и решил написать логику с нуля:
// if there's enough bright light in both sensors at the same time
// robot will move forward forever.
if (index > 7 && index2 > 7)
goForward(lp, rp, 1);
// but if there's not enough bright light anymore (i.e. reached black tape)
// proceed to the else-statement.
else {
// if left sensor detects the black tape then turn right
// if doesn't detect the black tape then keep going forward
if (index2 <= 7)
turnRight(lp, rp, 1);
else
goForward(lp, rp, 1);
// if right sensor detects the black tape then turn left
// if it doesn't detect the black tape then keep going forward
if (index <= 7)
turnLeft(lp, rp, 1);
else
goForward(lp, rp, 1);
}
// The reason for turnLeft and turnRight is to keep robot re-alligning
// to the black tape. It will happen so fast (every 1ms) that the jerking
// shouldn't even be noticeable.