а можно как то сделать чтобы при обнаружении одним из датчиков линии робот останавливался ненадолго, потом делал небольшой разворот в нужную сторону и продолжал движение и т.д.?или это тоже не поможет?
тяжело так настраивать программу когда макета рядом нет и занимаешься телепатией. ну да ладно. поиграйтесь с параметрами sped turn pausa/ вам это быстрее и проще
yanbaev72 Вы меня извените, но не подскажите вы сделали робота по линии. А то я тоже не могу сделать. Взял скетч с поста 73 он не реагирует на линию тоже самое что и у Вас на видео едит сам куда-то. Детали использую как у Вас.
50мсек может оказаться слишком большой паузой, особенно для "библиотечных" методов управления. Понизьте скорость моторов до приемлемой величины и будет ехать "только так", если датчики работают верно. Пост №73 - вариация самого простого метода управления:
// читаем датчики в переменные. Тут читаем цифровые датчики.
// можно заменить на аналоговые, чуть сложнее но тоже в результате получаем белое/черное
sensorLeft = digitalRead(pinLeftSensor);
sensorRight = digitalRead(pinRightSensor);
if( sensorLeft == sensorRight ){
// оба датчика видят белое или черное одновременно
// оба черных - перекресток?
// Пофиг, едем прямо, тут сразу на максю скорости.
// Можно сделать сложнее, с плавным приростом или выравниванием скоростей моторов..
speedLeft = speedRight = MAX_SPEED;
} else if( sensorLeft == LINE_BLACK ){
// левый видит линию - тормозим ЛЕВЫМ же колесом..
// ещё можно ускорять правое колесо, если есть куда..
// или плавно изменять скорости внешнего и внутреннего колеса..
speedLeft = 0;
} else if( sensorRight == LINE_BLACK ){
// правый видит линию - тормозим правым колесом..
// аналогично можно ускорять левое колесо..
speedRight = 0;
}
// одновременно управляем обоими моторами,
// иначе один мотор будет всегда откликаться раньше другого,
// что приведет к неодинаковости поворотов вправо и влево..
// тут же: если скорость мотора нулевая - отключаем его нафиг вовсе.
setMotorsSpeed(speedLeft, speedRight);
Но мне больше нравится такой вариант:
// читаем датчики в глобальные переменные sensorLeft, sensorRight.
// Как функцию реализовали - так и читаем. Можем даже усреднять и блокировать
// ошибки срабатывания датчиков внутри..
getSensors();
if( sensorLeft == sensorRight ){
// оба датчика видят белое или черное одновременно:
// едем прямо, формируя глобальные переменные speedLeft,speedRight
moveForward();
} else {
// упс .. поворот: вычисляем скорости согласно датчикам:
moveRotate();
}
setMotorsSpeed(speedLeft, speedRight);
Его достоинство в том, что как реализуете функции - так оно и поедет. Хотите просто, сложно с ПИД регулятором, ещё как-то .. да не проблема. :)
#define LeftPWM1 9
#define LeftDIR1 8
#define RightPWM2 10
#define RightDIR2 11
#define encoder0pinA 2
#define encoder0pinB 3
byte Left = 0;
byte Right = 0;
byte PrewStateLeft = 0;
byte PrewStateRight = 0;
void setup()
{
pinMode(LeftDIR1, OUTPUT);
pinMode(RightDIR2, OUTPUT);
}
void loop()
{
Left = digitalRead(encoder0pinA);
Left = !Left;
Right = digitalRead(encoder0pinB);
Right = !Right;
if (Left){
if (Right){ // Движение вперед
Forward();
PrewStateLeft = 1;
PrewStateRight = 1;
}else{ // Поворот в ЛЕВО
TurnLeft();
PrewStateLeft = 1;
PrewStateRight = 0;
}
}else{
if (Right){ // Поворот в ПРАВО
TurnRight();
PrewStateLeft = 0;
PrewStateRight = 1;
}else{
if (PrewStateLeft){
if (PrewStateRight){
TurnLeft();
}else{
TurnLeft();
}
}else{
if (PrewStateRight){
TurnRight();
}else{
TurnRight();
}
}
}
}
delay(10);
}
void TurnLeft(){
digitalWrite(LeftDIR1, 1);
digitalWrite(RightDIR2, 1);
analogWrite(LeftPWM1, 60); //PWM Speed Control
analogWrite(RightPWM2, 128); //PWM Speed Control
}
void TurnRight(){
digitalWrite(LeftDIR1, 1);
digitalWrite(RightDIR2, 1);
analogWrite(LeftPWM1, 128); //PWM Speed Control
analogWrite(RightPWM2, 60); //PWM Speed Control
}
void Forward(){
digitalWrite(LeftDIR1, 1);
digitalWrite(RightDIR2, 1);
analogWrite(LeftPWM1, 80); //PWM Speed Control
analogWrite(RightPWM2, 80); //PWM Speed Control
}
Сенсор видит черную линию как "0", а поле как "1", по этому делаю инверсию сигнала для более удобной работы в коде. Сам код простой: два датчика возвращают "0" либо "1", где "1" - линия. Робот старается поворачиваться в сторону единицы. Если линия потеряна, то робот движется и поворачивает в сторону последнего положения линии, которое он запомнил:
Мне не очень нравится как он ездит. Во-первых, дергается. Каждый поворот, или выравнивание - это рывок. Надо как-то сделать плавное регулирование скоростью моторов.
Еще нюанс: при потере линии (или ее поиске) он движется по кругу, по четкой траектории, иногда это не лучший вариант, так как он может "наматывать круги" между линиями, так и не доезжая до них... Надо как-то сделать динамически меняющуюся траекторию движения.
+ Хочу добавить датчик расстояния HC-SR04, чтобы робот объезжал препятствия и/или останавливался перед ними.
Начал бороться с рывками во время поворотов. Вот скетч:
#define LeftPWM1 9
#define LeftDIR1 8
#define RightPWM2 10
#define RightDIR2 11
#define encoder0pinA 2
#define encoder0pinB 3
byte Left = 0;
byte Right = 0;
byte PrewStateLeft = 0;
byte PrewStateRight = 0;
byte SpeedL = 0;
byte SpeedR = 0;
#define SpeedMax 150
#define SpeedMin 70
byte SpeedMidl = 0;
void setup()
{
pinMode(LeftDIR1, OUTPUT);
pinMode(RightDIR2, OUTPUT);
SpeedMidl = (SpeedMax + SpeedMin)/2;
}
void loop()
{
Left = digitalRead(encoder0pinA);
Left = !Left;
Right = digitalRead(encoder0pinB);
Right = !Right;
if (Left){
if (Right){ // Движение вперед
Forward();
PrewStateLeft = 1;
PrewStateRight = 1;
}else{ // Поворот в ЛЕВО
TurnLeft();
PrewStateLeft = 1;
PrewStateRight = 0;
}
}else{
if (Right){ // Поворот в ПРАВО
TurnRight();
PrewStateLeft = 0;
PrewStateRight = 1;
}else{
if (PrewStateLeft){ // если потеряна линия
if (PrewStateRight){ // Поворот в ЛЕВО
TurnLeft();
}else{
TurnLeft();
}
}else{
if (PrewStateRight){ // Поворот в ПРАВО
TurnRight();
}else{
TurnRight();
}
}
}
}
delay(5);
}
void TurnLeft(){
if(SpeedL > SpeedMin){ // уменьшаем скорость левого колеса
SpeedL--;
}
if(SpeedR < SpeedMax){ // увеличиваем скорость правого колеса
SpeedR++;
}
digitalWrite(LeftDIR1, 1);
digitalWrite(RightDIR2, 1);
analogWrite(LeftPWM1, SpeedL); //PWM Speed Control
analogWrite(RightPWM2, SpeedR); //PWM Speed Control
}
void TurnRight(){
if(SpeedR > SpeedMin){ // уменьшаем скорость правого колеса
SpeedR--;
}
if(SpeedL < SpeedMax){ // увеличиваем скорость левого колеса
SpeedL++;
}
digitalWrite(LeftDIR1, 1);
digitalWrite(RightDIR2, 1);
analogWrite(LeftPWM1, SpeedL); //PWM Speed Control
analogWrite(RightPWM2, SpeedR); //PWM Speed Control
}
void Forward(){
if(SpeedL < SpeedMidl){ // выравнивание скорости
SpeedL++;
}else if(SpeedL > SpeedMidl){
SpeedL--;
}
if(SpeedR < SpeedMidl){
SpeedR++;
}else if(SpeedR > SpeedMidl){
SpeedR--;
}
digitalWrite(LeftDIR1, 1);
digitalWrite(RightDIR2, 1);
analogWrite(LeftPWM1, SpeedL); //PWM Speed Control
analogWrite(RightPWM2, SpeedR); //PWM Speed Control
}
Рывки стали более плавными, но робот постоянно норовит уехать с линии. Если раньше робот ехал более-менее ровно, то теперь он виляет, и постоянно съезжает с линии. Можете подсказать что не так в коде?
После 1000 и 1 теста выяснил, что добиться плавного движения имея только 2 датчика в принципе не возможно... Просто потому что робот не знает под каким углом он заходит на линию. А угол может быть как острым, почти соответствующим направлению движения, так и под 90 градусов... Определить это только двумя датчиками слишком сложно. Нужно жестко привязываться к скорости движения, времени, и рассчитывать пройденный путь. К тому же "въезд" может быть не на прямую линию, а на имеющую изгиб... В общем не вижу смысла изобретать искусственный интеллект, когда задача решается добавлением в схему еще 2-4 датчиков (чем больше, тем лучше).
Вопрос по дальномеру HC-SR04. Сделать остановку робота при обнаружении препятствия - не проблема. Вопрос в том как бы грамотно "обучить" робота объезжать препятствия?
залейте скетч из 5 поста. машинка должна просто туда сюда кататься
залейте скетч из 5 поста. машинка должна просто туда сюда кататься
С этим скетчем все впорядке, машинка плавно разгоняется вперед, потом также плавно назад..
Нашел у себя драйвер L293DNE, с этой микрухой с питанием тоже все нормально когда ее на шилде ставлю вместо родной L293D
пробуйте
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 200 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(BACKWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 & sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 & sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 & sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 & sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }залейте скетч из 5 поста. машинка должна просто туда сюда кататься
С этим скетчем все впорядке, машинка плавно разгоняется вперед, потом также плавно назад..
Можно и обойтись просто будет слышен писк. И дело совсем не в этом, а том что - посмотрите что у вас за микросхема по середине шилда... и все поймете.
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); void setup() { // turn on motor Left.run(RELEASE); Right.run(RELEASE); } void loop() { Right.run(BACKWARD); Left.run(FORWARD); for(int i = 0; i < 255; i++) { Right.setSpeed(i); Left.setSpeed(i); delay(10); } for(int i = 255; i != 0; i--) { Right.setSpeed(i); Left.setSpeed(i); delay(10); } Left.run(BACKWARD); Right.run(FORWARD); for(int i = 0; i < 255; i++) { Right.setSpeed(i); Left.setSpeed(i); delay(10); } for(int i = 255; i != 0; i--) { Right.setSpeed(i); Left.setSpeed(i); delay(10); } Right.run(RELEASE); Left.run(RELEASE); delay(1000); }...
Но все равнопосле его заливки ни чего не происходит почему то....
А должен крутиться на месте сначала в одну сторону, а затем в другую, значит не верно подключены двигатели.
поменяйте местами провода на правом двигателе
код поправил.
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 200 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(FORWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 & sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 & sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 & sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 & sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }а машинка с кодом максима должна крутиться только
пробуйте
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 200 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(BACKWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 & sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 & sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 & sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 & sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }Таже беда...
залейте скетч из 5 поста. машинка должна просто туда сюда кататься
С этим скетчем все впорядке, машинка плавно разгоняется вперед, потом также плавно назад..
Можно и обойтись просто будет слышен писк. И дело совсем не в этом, а том что - посмотрите что у вас за микросхема по середине шилда... и все поймете.
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); void setup() { // turn on motor Left.run(RELEASE); Right.run(RELEASE); } void loop() { Right.run(BACKWARD); Left.run(FORWARD); for(int i = 0; i < 255; i++) { Right.setSpeed(i); Left.setSpeed(i); delay(10); } for(int i = 255; i != 0; i--) { Right.setSpeed(i); Left.setSpeed(i); delay(10); } Left.run(BACKWARD); Right.run(FORWARD); for(int i = 0; i < 255; i++) { Right.setSpeed(i); Left.setSpeed(i); delay(10); } for(int i = 255; i != 0; i--) { Right.setSpeed(i); Left.setSpeed(i); delay(10); } Right.run(RELEASE); Left.run(RELEASE); delay(1000); }...
Но все равнопосле его заливки ни чего не происходит почему то....
А должен крутиться на месте сначала в одну сторону, а затем в другую, значит не верно подключены двигатели.
Со стандартным драйвером шилда L293D не работало, поставил L293DNE и все заработало... я имею ввиду скетч из 5го поста...
по поводу того что должен крутится....в скетче была ошибка или не точность не знаю...
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 200 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(BACKWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 & sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 & sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 & sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 & sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }в строке 20-21 должно быть FORWARD на обоих моторах....
поэтому вчера перекидывал провода на правом моторе...
сейчас вернул все обратно
пробуйте
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 200 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(BACKWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 & sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 & sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 & sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 & sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }Таже беда...
не реагирует? попробуйте просто листок бумаги под датчики подносить. машинку держите в руках. будут изменения или нет
да насчет forward я заметил сейчас. поправил уже в 55 посте
да насчет forward я заметил сейчас. поправил уже в 55 посте
я немного изменил код
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 75 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define stope 0 #define pausa 50 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(FORWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 & sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 & sens_R==1){ //справа наехали на линию Left.setSpeed(turn); Right.setSpeed(stope); } if(sens_L==1 & sens_R==0){ //слева наехали на линию Left.setSpeed(stope); Right.setSpeed(turn); } if(sens_L==1 & sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }чтобы четко было видно реакцию....
сейчас скину видео
да насчет forward я заметил сейчас. поправил уже в 55 посте
вот видео
а это разве не вчерашнее видео?
Только все & нужно заменить на &&.
вот видео
Только все & нужно заменить на &&.
блин до сих пор делаю такие ошибки))) спасбио максим
= и == уже не путаю
поправил код. пробуй
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 200 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(FORWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 && sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 && sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 && sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 && sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }вот видео
http://www.youtube.com/watch?v=gcusWkVdRz8&feature=youtu.be
Только все & нужно заменить на &&.
блин до сих пор делаю такие ошибки))) спасбио максим
= и == уже не путаю
поправил код. пробуй
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 200 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(FORWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 && sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 && sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 && sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 && sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }работает, но такое ощущение что не успевает реагироватьи проскакивает линию
Снизьте скорость или увеличьте turn.
Снизьте скорость или увеличьте turn.
не помогает....
а можно как то сделать чтобы при обнаружении одним из датчиков линии робот останавливался ненадолго, потом делал небольшой разворот в нужную сторону и продолжал движение и т.д.?или это тоже не поможет?
+ вот вэтом видео http://www.youtube.com/watch?feature=player_embedded&v=y66X76bHlX8#t=9 робот ездит нормально
автор статьи утверждает что в скетче реализован игнор ошиок
// Моторы подключаются к клеммам M1+,M1-,M2+,M2- // Motor shield использует четыре контакта 6,5,7,4 для управления моторами #define SPEED_LEFT 6 #define SPEED_RIGHT 5 #define DIR_LEFT 7 #define DIR_RIGHT 4 #define LEFT_SENSOR_PIN 9 #define RIGHT_SENSOR_PIN 10 // Скорость, с которой мы движемся вперёд (0-255) #define SPEED 100 // Скорость прохождения сложных участков #define SLOW_SPEED 35 #define BACK_SLOW_SPEED 30 #define BACK_FAST_SPEED 50 // Коэффициент, задающий во сколько раз нужно затормозить // одно из колёс для поворота #define BRAKE_K 4 #define STATE_FORWARD 0 #define STATE_RIGHT 1 #define STATE_LEFT 2 #define SPEED_STEP 2 #define FAST_TIME_THRESHOLD 500 int state = STATE_FORWARD; int currentSpeed = SPEED; int fastTime = 0; void runForward() { state = STATE_FORWARD; fastTime += 1; if (fastTime < FAST_TIME_THRESHOLD) { currentSpeed = SLOW_SPEED; } else { currentSpeed = min(currentSpeed + SPEED_STEP, SPEED); } analogWrite(SPEED_LEFT, currentSpeed); analogWrite(SPEED_RIGHT, currentSpeed); digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void steerRight() { state = STATE_RIGHT; fastTime = 0; // Замедляем правое колесо относительно левого, // чтобы начать поворот analogWrite(SPEED_RIGHT, 0); analogWrite(SPEED_LEFT, SPEED); digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void steerLeft() { state = STATE_LEFT; fastTime = 0; analogWrite(SPEED_LEFT, 0); analogWrite(SPEED_RIGHT, SPEED); digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void stepBack(int duration, int state) { if (!duration) return; // В зависимости от направления поворота при движении назад будем // делать небольшой разворот int leftSpeed = (state == STATE_RIGHT) ? BACK_SLOW_SPEED : BACK_FAST_SPEED; int rightSpeed = (state == STATE_LEFT) ? BACK_SLOW_SPEED : BACK_FAST_SPEED; analogWrite(SPEED_LEFT, leftSpeed); analogWrite(SPEED_RIGHT, rightSpeed); // реверс колёс digitalWrite(DIR_RIGHT, LOW); digitalWrite(DIR_LEFT, LOW); delay(duration); } void setup() { // Настраивает выводы платы 4,5,6,7 на вывод сигналов for(int i = 4; i <= 7; i++) pinMode(i, OUTPUT); // Сразу едем вперёд runForward(); } void loop() { // Наш робот ездит по белому полю с чёрным треком. В обратном случае не нужно // инвертировать значения с датчиков boolean left = !digitalRead(LEFT_SENSOR_PIN); boolean right = !digitalRead(RIGHT_SENSOR_PIN); // В какое состояние нужно перейти? int targetState; if (left == right) { // под сенсорами всё белое или всё чёрное // едем вперёд targetState = STATE_FORWARD; } else if (left) { // левый сенсор упёрся в трек // поворачиваем налево targetState = STATE_LEFT; } else { targetState = STATE_RIGHT; } if (state == STATE_FORWARD && targetState != STATE_FORWARD) { int brakeTime = (currentSpeed > SLOW_SPEED) ? currentSpeed : 0; stepBack(brakeTime, targetState); } switch (targetState) { case STATE_FORWARD: runForward(); break; case STATE_RIGHT: steerRight(); break; case STATE_LEFT: steerLeft(); break; } }как бы этот скетч скрестить с библиотекой <AFMotor.h>? такое возможно
попробуйте так
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 80 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 50 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(FORWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 && sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 && sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 && sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 && sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }попробуйте так
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 80 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 50 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(FORWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 && sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 && sens_R==1){ //справа наехали на линию Left.setSpeed(sped); Right.setSpeed(turn); } if(sens_L==1 && sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped); } if(sens_L==1 && sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }все равно проскакивает....
если делаю скорость меньше 70 то робот не едет т.к. не хватает мощности тащить всю платформу....
#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 50 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(FORWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 && sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 && sens_R==1){ //справа наехали на линию Left.setSpeed(sped-20); Right.setSpeed(turn); } if(sens_L==1 && sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped-20); } if(sens_L==1 && sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }#include <AFMotor.h> AF_DCMotor Left(1, MOTOR12_64KHZ); AF_DCMotor Right(2, MOTOR12_64KHZ); #define led_1 9 //левый датчик #define led_2 10 //правый датчик #define sped 100 //зададим максимум скорости #define turn 50 //зададим скорость на повороте колеса тормозящего #define pausa 50 //пауза между опросами датчиков boolean sens_L = 0; //переменные для хранения состояния датчиков boolean sens_R = 0; void setup(){ Left.run(RELEASE); Right.run(RELEASE); pinMode(led_1, INPUT); pinMode(led_2, INPUT); Right.run(FORWARD); Left.run(FORWARD); } void loop(){ sens_L = digitalRead(led_1); sens_R = digitalRead(led_2); if(sens_L==0 && sens_R==0){ //если все норм едем вдоль линии Left.setSpeed(sped); Right.setSpeed(sped); } if(sens_L==0 && sens_R==1){ //справа наехали на линию Left.setSpeed(sped-20); Right.setSpeed(turn); } if(sens_L==1 && sens_R==0){ //слева наехали на линию Left.setSpeed(turn); Right.setSpeed(sped-20); } if(sens_L==1 && sens_R==1){ //мы на чем то но не на белой бумаге. встаем Left.setSpeed(0); Right.setSpeed(0); } delay(pausa); }меняется только скорость, а "поведение" остается тем же
в перевернутом виде реакция нормальная какая и должна быть, а в нормальном робот просто проскакивает линию и не успевает сделать какой то маневр..
в перевернутом? это в руках с поднесенными бумажками?
в перевернутом? это в руках с поднесенными бумажками?
под словосочетанием "в перевернутом состоянии" я как раз и имел ввиду что в руках поднося бумажку с черной линией
приложите видео в перевернутом виде, какой расстояноие от датчика до бумаги на полу и в руках?
приложите видео в перевернутом виде, какой расстояноие от датчика до бумаги на полу и в руках?
так на полу тоже реагирует, когда колеса чуть приподнять чтобы не катилась, но как отпускаешь она проскакивает линию...
датчики реагируют нормально, это видно по красным индикаторам которые загораются или тухнут..
тяжело так настраивать программу когда макета рядом нет и занимаешься телепатией. ну да ладно. поиграйтесь с параметрами sped turn pausa/ вам это быстрее и проще
Доброе время суток!
yanbaev72 Вы меня извените, но не подскажите вы сделали робота по линии. А то я тоже не могу сделать. Взял скетч с поста 73 он не реагирует на линию тоже самое что и у Вас на видео едит сам куда-то. Детали использую как у Вас.
50мсек может оказаться слишком большой паузой, особенно для "библиотечных" методов управления. Понизьте скорость моторов до приемлемой величины и будет ехать "только так", если датчики работают верно. Пост №73 - вариация самого простого метода управления:
// читаем датчики в переменные. Тут читаем цифровые датчики. // можно заменить на аналоговые, чуть сложнее но тоже в результате получаем белое/черное sensorLeft = digitalRead(pinLeftSensor); sensorRight = digitalRead(pinRightSensor); if( sensorLeft == sensorRight ){ // оба датчика видят белое или черное одновременно // оба черных - перекресток? // Пофиг, едем прямо, тут сразу на максю скорости. // Можно сделать сложнее, с плавным приростом или выравниванием скоростей моторов.. speedLeft = speedRight = MAX_SPEED; } else if( sensorLeft == LINE_BLACK ){ // левый видит линию - тормозим ЛЕВЫМ же колесом.. // ещё можно ускорять правое колесо, если есть куда.. // или плавно изменять скорости внешнего и внутреннего колеса.. speedLeft = 0; } else if( sensorRight == LINE_BLACK ){ // правый видит линию - тормозим правым колесом.. // аналогично можно ускорять левое колесо.. speedRight = 0; } // одновременно управляем обоими моторами, // иначе один мотор будет всегда откликаться раньше другого, // что приведет к неодинаковости поворотов вправо и влево.. // тут же: если скорость мотора нулевая - отключаем его нафиг вовсе. setMotorsSpeed(speedLeft, speedRight);Но мне больше нравится такой вариант:
// читаем датчики в глобальные переменные sensorLeft, sensorRight. // Как функцию реализовали - так и читаем. Можем даже усреднять и блокировать // ошибки срабатывания датчиков внутри.. getSensors(); if( sensorLeft == sensorRight ){ // оба датчика видят белое или черное одновременно: // едем прямо, формируя глобальные переменные speedLeft,speedRight moveForward(); } else { // упс .. поворот: вычисляем скорости согласно датчикам: moveRotate(); } setMotorsSpeed(speedLeft, speedRight);Его достоинство в том, что как реализуете функции - так оно и поедет. Хотите просто, сложно с ПИД регулятором, ещё как-то .. да не проблема. :)
Спасибо! Буду пробывать.
Всем привет!
Продолжу тему. Что есть в наличии:
- UNO (но поставлю Pro Mini для уменьшения размера).
- Драйвер двух моторов с управлением через ШИМ: https://bit.ly/2XoILxN
- Шасси: https://bit.ly/34qwvy5
- Энкодер: https://bit.ly/2UVvF9E
Мой скетч:
#define LeftPWM1 9 #define LeftDIR1 8 #define RightPWM2 10 #define RightDIR2 11 #define encoder0pinA 2 #define encoder0pinB 3 byte Left = 0; byte Right = 0; byte PrewStateLeft = 0; byte PrewStateRight = 0; void setup() { pinMode(LeftDIR1, OUTPUT); pinMode(RightDIR2, OUTPUT); } void loop() { Left = digitalRead(encoder0pinA); Left = !Left; Right = digitalRead(encoder0pinB); Right = !Right; if (Left){ if (Right){ // Движение вперед Forward(); PrewStateLeft = 1; PrewStateRight = 1; }else{ // Поворот в ЛЕВО TurnLeft(); PrewStateLeft = 1; PrewStateRight = 0; } }else{ if (Right){ // Поворот в ПРАВО TurnRight(); PrewStateLeft = 0; PrewStateRight = 1; }else{ if (PrewStateLeft){ if (PrewStateRight){ TurnLeft(); }else{ TurnLeft(); } }else{ if (PrewStateRight){ TurnRight(); }else{ TurnRight(); } } } } delay(10); } void TurnLeft(){ digitalWrite(LeftDIR1, 1); digitalWrite(RightDIR2, 1); analogWrite(LeftPWM1, 60); //PWM Speed Control analogWrite(RightPWM2, 128); //PWM Speed Control } void TurnRight(){ digitalWrite(LeftDIR1, 1); digitalWrite(RightDIR2, 1); analogWrite(LeftPWM1, 128); //PWM Speed Control analogWrite(RightPWM2, 60); //PWM Speed Control } void Forward(){ digitalWrite(LeftDIR1, 1); digitalWrite(RightDIR2, 1); analogWrite(LeftPWM1, 80); //PWM Speed Control analogWrite(RightPWM2, 80); //PWM Speed Control }Сенсор видит черную линию как "0", а поле как "1", по этому делаю инверсию сигнала для более удобной работы в коде. Сам код простой: два датчика возвращают "0" либо "1", где "1" - линия. Робот старается поворачиваться в сторону единицы. Если линия потеряна, то робот движется и поворачивает в сторону последнего положения линии, которое он запомнил:
Вот видео как он ездит: https://www.youtube.com/watch?v=1CL2ENXPybI
Мне не очень нравится как он ездит. Во-первых, дергается. Каждый поворот, или выравнивание - это рывок. Надо как-то сделать плавное регулирование скоростью моторов.
Еще нюанс: при потере линии (или ее поиске) он движется по кругу, по четкой траектории, иногда это не лучший вариант, так как он может "наматывать круги" между линиями, так и не доезжая до них... Надо как-то сделать динамически меняющуюся траекторию движения.
+ Хочу добавить датчик расстояния HC-SR04, чтобы робот объезжал препятствия и/или останавливался перед ними.
Начал бороться с рывками во время поворотов. Вот скетч:
#define LeftPWM1 9 #define LeftDIR1 8 #define RightPWM2 10 #define RightDIR2 11 #define encoder0pinA 2 #define encoder0pinB 3 byte Left = 0; byte Right = 0; byte PrewStateLeft = 0; byte PrewStateRight = 0; byte SpeedL = 0; byte SpeedR = 0; #define SpeedMax 150 #define SpeedMin 70 byte SpeedMidl = 0; void setup() { pinMode(LeftDIR1, OUTPUT); pinMode(RightDIR2, OUTPUT); SpeedMidl = (SpeedMax + SpeedMin)/2; } void loop() { Left = digitalRead(encoder0pinA); Left = !Left; Right = digitalRead(encoder0pinB); Right = !Right; if (Left){ if (Right){ // Движение вперед Forward(); PrewStateLeft = 1; PrewStateRight = 1; }else{ // Поворот в ЛЕВО TurnLeft(); PrewStateLeft = 1; PrewStateRight = 0; } }else{ if (Right){ // Поворот в ПРАВО TurnRight(); PrewStateLeft = 0; PrewStateRight = 1; }else{ if (PrewStateLeft){ // если потеряна линия if (PrewStateRight){ // Поворот в ЛЕВО TurnLeft(); }else{ TurnLeft(); } }else{ if (PrewStateRight){ // Поворот в ПРАВО TurnRight(); }else{ TurnRight(); } } } } delay(5); } void TurnLeft(){ if(SpeedL > SpeedMin){ // уменьшаем скорость левого колеса SpeedL--; } if(SpeedR < SpeedMax){ // увеличиваем скорость правого колеса SpeedR++; } digitalWrite(LeftDIR1, 1); digitalWrite(RightDIR2, 1); analogWrite(LeftPWM1, SpeedL); //PWM Speed Control analogWrite(RightPWM2, SpeedR); //PWM Speed Control } void TurnRight(){ if(SpeedR > SpeedMin){ // уменьшаем скорость правого колеса SpeedR--; } if(SpeedL < SpeedMax){ // увеличиваем скорость левого колеса SpeedL++; } digitalWrite(LeftDIR1, 1); digitalWrite(RightDIR2, 1); analogWrite(LeftPWM1, SpeedL); //PWM Speed Control analogWrite(RightPWM2, SpeedR); //PWM Speed Control } void Forward(){ if(SpeedL < SpeedMidl){ // выравнивание скорости SpeedL++; }else if(SpeedL > SpeedMidl){ SpeedL--; } if(SpeedR < SpeedMidl){ SpeedR++; }else if(SpeedR > SpeedMidl){ SpeedR--; } digitalWrite(LeftDIR1, 1); digitalWrite(RightDIR2, 1); analogWrite(LeftPWM1, SpeedL); //PWM Speed Control analogWrite(RightPWM2, SpeedR); //PWM Speed Control }После 1000 и 1 теста выяснил, что добиться плавного движения имея только 2 датчика в принципе не возможно... Просто потому что робот не знает под каким углом он заходит на линию. А угол может быть как острым, почти соответствующим направлению движения, так и под 90 градусов... Определить это только двумя датчиками слишком сложно. Нужно жестко привязываться к скорости движения, времени, и рассчитывать пройденный путь. К тому же "въезд" может быть не на прямую линию, а на имеющую изгиб... В общем не вижу смысла изобретать искусственный интеллект, когда задача решается добавлением в схему еще 2-4 датчиков (чем больше, тем лучше).
Добавь один или два датчика СЗАДИ робота. Таким образом ты можешь вычислять тренд влево или вправо.
Как вариант.
Вопрос по дальномеру HC-SR04. Сделать остановку робота при обнаружении препятствия - не проблема. Вопрос в том как бы грамотно "обучить" робота объезжать препятствия?
Матрица. Те-же тренды. Тут математики есть посильнее меня, у них алгоритм спрашивай.
В общем, вот то у меня получилось: https://youtu.be/CRBNUABEd-w
В общем, вот то у меня получилось: https://youtu.be/CRBNUABEd-w
Интересненько