Coche Autonomo

Introducción
El objetivo es llevar a cabo un proyecto con Arduino en grupo. El proyecto tiene 3 fases:
  1. Validación
  2. Desarrollo
  3. Presentación
En la primera fase se valida el tema del proyecto. En la segunda fase se lleva a cabo el
proyecto. Se busca, se crea y se codifica. Y en la última fase se defiende el proyecto delante
de todos.

                                                                                                                                                          

Descripción del proyecto
Nuestro proyecto es un coche autónomo construido y codificado con Arduino.
El coche autónomo:
  • Es un coche que es capaz de mover y girar autónomamente.
  • Tiene una fuente de energía externa.
  • Puede evitar los obstáculos en tiempo real.
Para el funcionamiento correcto del coche es necesario los siguientes componentes:
  • Energía externa: como una fuente de tensión o pilas.
  • Sensores para detectar obstáculos, por ejemplo un sensor ultrasónico.
  • Servo para girar el sensor para buscar camino óptimo.
  • Motores y controladores para el movimiento del coche.
  • Ruedas
  • Chassis
 
Materiales necesarios
Arduino Mega 2560 R3
Puede costar unos 5 euros o más. La original es muy cara. Las
copias viene baratas y sirven para poder realizar proyectos. Están
incluidas en los kits generales.
14€
Protoboard
Suele estar incluido en los kits generales de arduino.
2€
Cable USB
Suele venir junto con la placa de arduino. Cuesta unos 6 euros o más
con la placa de arduino.
Cables
Son baratas. Están incluidos en los kits generales y básicos.
Kit de coche
Viene con las ruedas, los motores, el chasis y el fuente de
alimentación de pilas.
20€
Bateria / Pilas
Están incluidos en algunos kits de arduino, no en el nuestro.
12€
Cargador
Suelen estar incluidos en los kits generales. Venia incluido.
Controlador de
motores
Normalmente no están incluidos. En algunos vienen junto con el
motor (1 unidad).
9,9€
Servo
Están incluidos en casi todos los kits generales. Los servos comunes
pueden girar hasta 180 grados.
12€
Sensor ultrasonico
HC-SR04
Están incluidos en la mayoría de los kits generales. Son capaces de
transmitir señales ultrasónicos y recibirlos durante un periodo.
5€
Soporte
Se utiliza como soporte para fijar el ultrasonido y el servo.
Se puede comprar o fabricar.
4,40
Kit comprado
Kit comprado por los alumnos, que contiene cableado,
transformador de corriente, ultrasonidos, servo, placa arduino, etc.
El kit completo esta valorado en 50€. Los kits para estudiantes y/o
generales están valorados entre 20-40 €.
TOTAL
~100€
 
Componentes
  • Arduino
Hay varias placas de arduino. Nosotros decidimos utilizar la del
“Arduino Mega 2560 R3”. La placa está diseñada para proyectos más complejos
disponiendo de más salidas digitales y analogicas que la placa Arduino Uno.
Decidimos utilizar esta placa en lugar de la de Arduino Uno para poder aprovechar
de la gran cantidad de puertos y minimizar la cantidad de cables usados. También
resulta más simple a la hora de escribir el código y asignar los puertos.
  • Componentes básicos
Protoboard:
Hay varias placas de inserción (protoboard) según su tamaño. Para ahorrar espacio
nosotro utilizamos la placa “protoboard mini”.
Cables:
Hay dos tipos cables: “macho-macho” (macho) y “macho-hembra” (hembra).
Los cables macho lo utilizamos en la placa de inserción y el arduino. Los cables
hembra los utilizamos para el controlador de motores.


Cables macho-macho
Cables macho-hembra
Kit del coche
Motores y ruedas
El kit del coche incluye cuatro motores y cuatro ruedas, una para cada motor. En
el kit también se encuentra el soporte de las pilas además del chasis donde se
montaran todos los componentes. Para controlar la velocidad y dirección en la que
giran los motores las ruedas, es necesario un controlador
Alimentación externa
Es necesario alimentar el coche con una fuente de tensión externa aparte para que
los motores tengan suficiente fuerza de torsión para girar las cuatro ruedas a una
velocidad determinada.
Chasis
El chasis es el material de soporte del coche. En el chasis caben todos los
componentes, incluyendo la placa de Arduino, placa de inserción, servo y el sensor
ultrasónico, además de los controladores, pilas, los motores y las ruedas.
  • Controlador de motores
Hay varios tipos de controladores de motores según su modelo” y/o fabricante y
según su capacidad,la cantidad de motores que puede controlar. Nosotro utilizamos
el controlador de motores “L298N” capaz de controlar dos motores a la vez.  
El controlador, el que utilizamos, tiene varios puertos:
    • 2 puertos PWM (ENA, ENB): controlan la potencia que de los motores A y B respectivamente.
    • 4 puertos digitales (IN1, IN2, IN3, IN4): controlan las direcciones que giran cada motor:
      • Motor A: IN1 y IN2
      • Motor B: IN3 y IN4
    • 2 salidas que alimentan cada motor:
      • Motor A: OUT1 y OUT2
      • Motor B: OUT3 y OUT4
    • 2 entradas de alimentación: 12V y 5V
    • GND: tierra
Para cambiar de sentido de giro se invierten los valores de los puertos digitales
entre “HIGH” y “LOW”. La potencia de cada motor vendrá dada por el valor que
se le asigna a el puerto PWM correspondiente.
  • Radar o detector de obstáculos
Para el radar se usará un Ultrasonido “HC-SR04” que envía señales ultrasónicos
y los recibe cada intervalo de tiempo. Para que el sensor ultrasónico actúe como un
radar, es decir vaya girando para poder detectar bien los obstáculos, lo conectamos
a un servo.
El servo es un dispositivo que va cambiando de ángulo. Puede ir desde 0 grados a
180 grados. El ángulo de giro se controla con el código, lo cual nos permite elegir los
ángulos específicos.


Ultrasonido: HC-SR04
Servo: Tower PRO SG-90


 
Desarrollo y Funcionamiento del proyecto
  • Radar
Ultrasonido
Para poder detectar objetos tenemos un ultrasonido montado sobre un servo que
manda y recibe señales para calcular las distancias a los obstáculos. Con el Trig
conectado al puerto A5, mandamos unos pulsos o señales y escuchamos con el
Echo conectado al puerto A6. El tiempo que tarda en que se manda y recibe la
señal se usa para calcular la distancia al objeto que apunta.
Servo
Para que el ultrasonido actué como un tipo de radar, se programó el servo para que
complete un barrido de 180 grados. Con el ultrasonido montado en el mismo servo
leemos la distancia cada 45 grados de izquierda a derecha para elegir una dirección.
Durante el barrido la primera dirección sin obstáculos es la que se elige y el servo
vuelve a su posición inicial de 90 grados. De este modo no requiere completar todo
el barrido cada vez que se encuentre un obstáculo.

  • Controlador de Motores
Cada controlador dirige dos motores usando 3 pines por cada motor.
Los pines digitales son para girar los motores en un sentido u otro, IN1 e IN2
corresponden con el motor A y IN3 e IN4 con el motor B. El tercer pin de control
es PWM que se usa para regular la potencia de cada motor pasandole un valor
entre 0 y 255. El ENA y ENB corresponden respectivamente al motor A y B. Para
el funcionamiento correcto de los motores tenemos la siguiente tabla lógica:
Decidimos programar las ruedas para que giren todas a la vez en los sentidos
correctos para completar los giros que debe hacer el coche. Para completar un
giro a la izquierda, por ejemplo, las ruedas a la izquierda del coche giran hacia
atrás y las ruedas a la derecha giran en sentido contrario.
  • Funcionamiento
Para controlar los movimientos del coche, se usará el radar en conjunto con los controladores y sus correspondientes motores y ruedas. Cuando se carga el programa el radar empieza a leer distancias. Lo hace, continuamente mandando pulsos ultrasónicos, para detectar obstáculos calculando la distancia hacia adelante. En caso de encontrar algún obstáculo en su camino, se calcula la distancia al obstáculo y  se comprueba si es menor que 30 cm. Si se cumple esta condición, el coche se detiene y realiza un barrido con el radar. El radar puede llegar a hacer 5 lecturas durante el barrido, buscando el camino que este libre. Como se comentó antes, se elige el primer camino sin obstáculos que se encuentra. Cuando encuentra el primer camino libre, el radar vuelve a su posición inicial antes de que gire el coche para que antes de avanzar poder realizar una lectura por si el camino se ha obstruido de repente. Si el radar completa el barrido entero y no ha encontrado ningún camino libre el coche hace un giro de 180 grados en su sitio y empieza de nuevo.


Video
 
Comentario final
 
  • Posibles mejoras
El proyecto se puede mejorar de muchas maneras. Algunas ideas que se nos han ocurrido
son:
    • Añadir otro sensor para que el coche pueda detectar obstáculos por detrás.
    • Utilizar sensor de luz aparte de la de ultrasonido para mejorar la detección de los

      obstáculos.

    • Mejorar la detección de obstáculos. Actualmente el radar detecta obstáculos en línea

      recta y hay algunos obstáculos que no es capaz de detectar.

    • Añadir una cámara y un procesador de imágenes para que pueda recorrer por un

      circuito y sea capaz de interpretar las señales de tráfico.

    • Añadir marchas y cambio de velocidad para que pueda seguir mejor las normas de

      tráfico y/o conducir de forma más segura.

    • Conectar un módulo wifi o bluetooth para poder dar avisos en caso de accidentes y

      robos.

    • Añadir sistema para poder llamar a una grúa.
    • Añadir un detector de huellas para evitar los robos.
    • Utilizar de pilas recargables y añadir placas solares para poder recargar las pilas y

      aumentar el tiempo de funcionamiento del coche.

    • Añadir un botón de inicio y de parada.
    • Añadir reconocimiento de voz para poner el coche en marcha o detenerlo.
    • Añadir un gps.
    • Mejorar el coche para que pueda aparcar por sí solo.
    • etc
  • Incorporación en el mundo real
En la actualidad gracias a las mejoras tecnológicas, la conducción autónoma en el
mundo real está más cerca de lo que pensamos aunque aún le faltan unos cuantos
años. Actualmente hay varios automóviles, en su mayoría coches que incorporan
sistema de reconocimiento de escenarios para realizar una conducción casi
autónoma o semi-autónoma, como en el caso de Tesla o incluso de Audi, con su A8.
En el mundo real hay muchos peligros. Uno de los peligros para nuestro coche
serian los materiales que aíslan el ruido. Esto pudiera causar que nuestro radar
no funcione correctamente. Además esto es sin tener en cuenta los problemas
que pueden surgir por las interferencias ajenas y el viento por nombrar algunas.
El coche autónomo se puede incorporar en el mundo real pero necesita varios
cambios para que el coche pueda ser utilizado como se espera. Por ejemplo en el
caso de nuestro coche necesitaría una cámara, un procesador de imágenes y cambio
de velocidad como mínimo. También sensores más eficaces para poder detectar bien
los obstáculos.
 
Referencias
Codigo
#include <Servo.h> //servo1 library


Servo servo;
/*Echo/Trig del ultrasonido */
int Echo = A6;  
int Trig = A5;


/*almacena distancia leida por ultrasonido*/
int dist;


/*MOTORES*/
/*define pins para controlar los motores*/
int in1=2;
int in2=4;
int in3=7;
int in4=8;
int in5=10;
int in6=11;
int in7=12;
int in8=13;


/*define pins de enable (PWM). Estos controlan la potencia de los motores*/
int ENA1=6;
int ENB1=9;
int ENA2=3;
int ENB2=5;


/*Calcula y devuelve distancia leida por ultrasonido*/
float Distance_test()  {
  digitalWrite(Trig, LOW);   
  delayMicroseconds(1);
  digitalWrite(Trig, HIGH);  
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);   
  float Fdistance = pulseIn(Echo, HIGH);  
  Fdistance = (Fdistance)/ 58;       
  Serial.print(“distancia: “);
  Serial.println(Fdistance);
  return Fdistance;
} 


/*Barrido del servo con el ultrasonido. Devuelve entero que corresponde con una direccion*/
int Servo_scan() {
    delay(500);
    servo.write(180);
    delay(500);
    dist = Distance_test(); 
    if (dist > 25) {
      servo.write(80);
      delay(1000);
      Serial.println(‘1’);
      return 1;
    } else {
      servo.write(135);
      delay(500);
      dist = Distance_test();
      delay(1000);
      if (dist > 25) {
        servo.write(80);
        delay(1000);
        Serial.println(‘2’);
        return 2;
      } else {       
        servo.write(80);
        delay(500);
        dist = Distance_test();
        delay(1000);
        if (dist > 25) {
          servo.write(80);
          delay(1000);
          Serial.println(‘3’);
          return 3;
        } else {         
          servo.write(40);
          delay(500);
          dist = Distance_test();
          delay(1000);
          if (dist > 25) {
            servo.write(80);
            delay(1000);
            Serial.println(‘4’);
            return 4;
          } else {         
            servo.write(0);
            delay(500);
            dist = Distance_test();
            delay(1000);
            if (dist > 25) {
              servo.write(80);
              delay(1000);
              Serial.println(‘5’);
              return 5;
            } else {
              servo.write(80);
              delay(1000);
              Serial.println(‘6’);
              return 6;
            }
          }
        }
      }
    }
}


/*MOTORES*/
/*retroceso NO EN USO*/
void _mback()
{ 
  analogWrite(ENA1,255);
  analogWrite(ENB1,255);
  analogWrite(ENA2,255);
  analogWrite(ENB2,255);
  
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);  //Right front wheel backward
  
  digitalWrite(in3,LOW);
  digitalWrite(in4,HIGH); //Left front wheel backward
  
  digitalWrite(in5,LOW);
  digitalWrite(in6,HIGH); //Right back wheel backward
  
  digitalWrite(in7,HIGH);
  digitalWrite(in8,LOW);  //Left back wheel backward
  
  Serial.println(“back”);
}


/*avanzar*/
void _mforward()
{
  analogWrite(ENA1,200);
  analogWrite(ENB1,200);
  analogWrite(ENA2,200);
  analogWrite(ENB2,200);
  
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH); //Right Front wheel forward
  
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);  //Left Front wheel forward
  
  digitalWrite(in5,HIGH);
  digitalWrite(in6,LOW);  //Right back wheel forward
  
  digitalWrite(in7,LOW);
  digitalWrite(in8,HIGH); //Left back wheel forward
  
  Serial.println(“forward”);
}


/*funcion para girar a la izquierda*/
void _mleft()
{
  analogWrite(ENA1,255);
  analogWrite(ENB1,255);
  analogWrite(ENA2,255);
  analogWrite(ENB2,255);
  
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH);
  
  digitalWrite(in3,LOW);
  digitalWrite(in4,HIGH);
  
  digitalWrite(in5,LOW);
  digitalWrite(in6,HIGH);
  
  digitalWrite(in7,LOW);
  digitalWrite(in8,HIGH);
  
  Serial.println(“left”);
}


/*funcion para girar a la derecha*/
void _mright()
{
  analogWrite(ENA1,255);
  analogWrite(ENB1,255);
  analogWrite(ENA2,255);
  analogWrite(ENB2,255);
  
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
  
  digitalWrite(in5,HIGH);
  digitalWrite(in6,LOW);
  
  digitalWrite(in7,HIGH);
  digitalWrite(in8,LOW);
  
  Serial.println(“right”);
}


void _stop()
{
  digitalWrite(ENA1,LOW);
  digitalWrite(ENB1,LOW);
  digitalWrite(ENA2,LOW);
  digitalWrite(ENB2,LOW);
  Serial.println(“Stop”);
}


/*decide el movimiento autonomo del coche*/
void movimientosAuto() {
  dist = Distance_test();   //Lee distancia de frente
  if (dist <= 30) {            
    _stop();                
    gira(Servo_scan());     //Gira en direccion devuelta por el servo scan
    _stop();
  } else {
    gira(3);
  }              
}


/*recibe un entero desde el Servo_scan() que dice en que direccion debe girar el coche*/
void gira(int dir) {
  switch(dir) {
    case 1:
      _mleft();     //gira izq este
      delay(500);   //90 grados
      break;
    case 2:
      _mleft();     //gira izq noreste
      delay(234);   //45 grados
      break;
    case 3:
      _mforward();  //recto
      break;
    case 4:
      _mright();    //gira der noroeste
      delay(250);   //45 grados
      break;
    case 5:
      _mright();    //gira der oeste
      delay(500);  //90 grados
      break;
    case 6:
      _mright();    //gira 180
      delay(935);
  }
  
}


void setup() 
{
  /*Conectamos Servo al pin 30*/
  servo.attach(30);
  /*Declaro el Echo como input y el Trig como output*/
  pinMode(Echo, INPUT);    
  pinMode(Trig, OUTPUT);
  /*MOTOR A1*/
  pinMode(in1,OUTPUT);
  pinMode(in2,OUTPUT);
  pinMode(ENA1,OUTPUT);
  /*Motor B1*/
  pinMode(in3,OUTPUT);
  pinMode(in4,OUTPUT);
  pinMode(ENB1,OUTPUT);
  /*Motor A2*/
  pinMode(in5,OUTPUT);
  pinMode(in6,OUTPUT);
  pinMode(ENA2,OUTPUT);
  /*Motor B2*/
  pinMode(in7,OUTPUT);
  pinMode(in8,OUTPUT);
  pinMode(ENB2,OUTPUT);
  
  Serial.begin(9600);
}


void loop() { 
  movimientosAuto();
  delay(250);
}

También te podría gustar...

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *