Sei sulla pagina 1di 15

ROBÓYICA Y MECATRÓNICA

PROF. JOSE ANTONIO LOPEZ OROZCO

PROYECTO ROBOT MÓVIL

Contenido
Aspectos generales ....................................................................................................................... 2
Materiales ..................................................................................................................................... 2
Diseño e Implementación Física.................................................................................................... 5
Programación ................................................................................................................................ 9

BUCHELI NARANJO, JOSÉ LUIS


JIMÉNEZ RUBIO, PABLO

2018-2019

1
Aspectos generales
Este proyecto de fin de carrera consiste en la programación y construcción de un pequeño robot
móvil autónomo basado en una tarjeta basado en un ARM. A lo largo del proyecto explicaremos
los diferentes requisitos tanto de software como de hardware necesarios para la realización del
proyecto, el diseño mismo del robot, las herramientas y el entorno utilizados, el desarrollo de la
programación y el hardware y para el funcionamiento del robot.

El robot que vamos a construir es un pequeño robot móvil que evita los obstáculos. A través de
unos sensores infrarrojos, detectará la distancia a los objetos que tiene frente a sí, además de
sensores ópticos de reflexión para determinar la distancia recorrida por el robot. Cuando se
acerque a una determinada distancia, el procesador enviara una señal hacia los motores para
que realicen el giro y así evitar el obstáculo.

La evasión de obstáculos y control de posición son características fundamentales para construir


robots con funciones más complejas volviéndolos robustos en condiciones complicadas en
medio de su trabajo.

Objetivos

1.- Construir plataforma robótica.

Materiales
1. MICROCONTROLADOR [1]

Tarjeta ARM
Raspberry Pi es un ordenador de placa única (SBC) de bajo coste, desarrollado en Reino
Unido por la Fundación Raspberry Pi (Universidad de Cambridge), con el objetivo de
estimular la enseñanza de ciencias de la computación en las escuelas. Aunque
desarrollado en 2006, su lanzamiento en el mercado fue sido en febrero de 2012.

Fig. Tarjeta Raspberry PI 2.

GPIO
El GPIO es el elemento más importante en las prácticas, puesto que permitirá conectar
la Raspberry Pi a distintos elementos hardware como, por ejemplo, sensores (de
ultrasonidos, infrarrojos), control de leds, motores, switches, etc.

2
Fig. GPIO Tarjeta Raspberry PI 2.

La librería WiringPi permite utilizar todos los pines del GPIO. La nomenclatura de los
pines que se suele utilizar es la BCM_GPIO o la numeración de WiringPi. En la siguiente
tabla puede observar la correspondencia entre los 40 pines del conector.

Fig. Nomenclaturas y su funcionalidad.

2. MÓDULO DE CONEXIÓN INALÁMBRICA

Adaptador Wifi USB

Fig. Stick Wifi.

Stick Wifi que se conecta directamente a un puerto USB. Es compatible tanto con
Raspberry Pi como con Beagle Bone y es soportado de forma nativa tanto por la
distribución Angstrom como Raspbian sin recompilar el kernel.

• Chippset: Realtek RTl8192cu


• Peso: 2.17g
• Estándares soportados: IEEE 802.11n (draft), IEEE 802.11g, IEEE 802.11b
• Interfaz USB2.0/1.1
• Data Rate: 802.11n: up to 150Mbps (downlink) and up to 150Mbps (uplink) ,
802.11g: 54 / 48 / 36 / 24 / 18/ 12 / 9 / 6 Mbps auto fallback, 802.11b: 11 / 5.5 / 2 /
1 Mbps auto fallback
• Potencia de salida: 13 ~17 dBm
• Modulación: 11n: BPSK, QPSK, 16QAM, 64QAM con OFDM, 11g: BPSK, QPSK,
16QAM, 64QAM, OFDM, 11b: DQPSK, DBPSK, DSSS, CCK
• Soporta Ad-Hoc
• Indicador LED Verde
• Temperatura de funcionamiento: 0 - 40°C

3
3. ACTUADOR

Servomotor
Este servo motor estándar de alto torque incluye engranajes metálicos para un torque
de 12,5 Kg./cm. Puede girar de manera continua (no tiene bloqueo de giro),
consiguiendo 360 grados.

Fig. Servomotor.
Características
• Giro continuo (no tiene tope de giro) 360 grados.
• Voltaje: 4,8 V - 7,2 V DC max. (se recomienda usar 5V a 6V).
• Velocidad promedio: 60 grados en 0,20 seg. (a 4,8 V), 60 grados en 0,16 seg. (a
6,0V).
• Tipo de conector: JR
• Torque: 4,8V: 8,5 kg/cm. 6V: 12,5 kg-cm.
• Tamaño mm: (L x W x H) 40,7 x 19,7 x 42,9 mm.

4. ELEMENTOS ADICIONALES

Rueda omnidireccional

De pivote o Rotatoria Sujeta a la superficie con una estructura que tiene un eje en su
centro, anclado a la rueda que puede girar libremente.

Fig. Rueda omnidireccional.


Rueda bidireccional
Rueda para acoplarla a un servomotor de rotación completa sin accesorio adicional,
tornillo de sujeción.
Dimensiones 69 x 7.6 mm

Fig. Rueda bidireccional.

4
Diseño e Implementación Física

Para construir el robot móvil lo primero considera las dimensiones de diseño de un chasis en el
que se instalara los componentes necesarios para su funcionamiento. Por este motivo se
determinó dimensiones próximas a las establecidas en el guion, se colocó una placa base que
alberga la batería de 10000mAh para alimentar toda la electrónica y sobre esta un segundo nivel
donde, reposara la tarjera Raspberry Pi, además se colocaran las diversas piezas que requiere el
robot.

Fig. Diseño chasis

La distribución de las piezas en el chasis es la siguiente:

• Los servomotores se instalarán en la parte lateral del chasis.


• Los sensores de infrarrojos irán ubicados en la parte frontal externa.
• Los sensores de proximidad ópticos irán ubicados en la parte inferior delantera.
• La rueda omnidireccional se añadirá en la parte inferior posterior.
• La batería se colocará en el nivel 1 y la electrónica en el siguiente nivel.

Teniendo ya la distribución de los diferentes componentes se realiza la implementación del


diseño del chasis.

1.- Para implementar el chasis se seleccionó madera de cedro por ser ligera y blanda, se realizó
cortes con las dimensiones establecidas para el chasis a partir del diseño previo y ensamblarlo,
con el chasis montado se procedió a instalar los servomotores.

Fig. Chasis y servomotores

2.- Instalados los servomotores se coloca la rueda loca, su ubicación conforme al diseño se
establece en la parte inferior del chasis, la misma que permitirá que el vehículo móvil pueda
desplazarse en diversas direcciones, deberá ajustarse de manera que el vehículo se encuentre
nivelado con respecto a la superficie en la que va a desplazarse, de está manera, manteniendo
su centro de masa y el auto equilibrado.

5
Fig. Colocación rueda loca

3.- Una vez instalada toda la electromecánica de desplazamiento en el vehículo, se coloca el


sistema de alimentación mismo que se encargara de suministrar la tensión y corriente requerida
para el funcionamiento de los servomotores, la tarjeta de procesamiento y sensores. El sistema
de alimentación es una batería externa de Xiaomi con su modelo de 10000 mAh y 2 puertos USB,
la misma estará ubicada en el primer nivel como se observa en la imagen.

Fig. Sistema de alimentación

4.- Terminado el chasis, el sistema electromecánico de desplazamiento y sistema de


alimentación se coloca la tarjeta de procesamiento Raspberry en el nivel 2 y se realiza las
conexiones de alimentación para los sistemas instalados, además del sistema de conexión
inalámbrico wifi.

Fig. Vista lateral del robot

SECCIÓN II - USO Y CALIBRACIÓN DE SENSORES DEL ROBOT

5.- Finiquitada la instalación de los sistemas de desplazamiento y alimentación, se procede a


colocar los sensores infrarrojos (GD2Y0a41SK0F – Sharp) en la parte frontal del chasis, así como
los sensores de proximidad ópticos (CNY70) en la parte inferior del chasis con las conexiones
para el sistema de alimentación y sistema de control, además se colocan en la parte interna de
las ruedas una plantilla de secciones claras y obscuras para el sistema de encoder el que
permitirá determinar la distancia recorrida por el robot en función de pulsos registrados por el
sistema de control.

6
Fig. Vista frontal y plantilla para encoder

En la imagen se aprecia los sensores infrarrojos en su parte frontal y las plantillas para el
encoder, mientras que la colocación de los sensores ópticos se construyó un sistema mecánico
que permita manipular la altura (h), la separación entre rueda – sensor (d) y ángulo de
proyección del haz incidente (r) sobre la plantilla para encoder.

Fig. Soporte mecánico para sensor óptico de reflexión.

Fig. Robot implementado vista frontal y superior.

7
Electrónica Implementada

A continuación de aprecia el circuito implementado para los servomotores y la tarjeta


Raspberry y su alimentación externa.

Fig. Circuito para control de actuadores mediante PWM.

SECCIÓN II

Se realizaron los circuitos de acondicionamiento, para el sensor analógico Sharp se procedió a


conectar directamente a un convertidor de analógico al digital de 8 bits MCP3008 debido a que
ya cuenta con su señal acondicionada para trabajar en un rango de 4 – 30 cm, mientras que el
sensor CNY70 requiere resistencias de acondicionamiento, para la máxima detección el diodo IR
la caída de voltaje debe estar entre 1.25V hasta 1.6V, por lo que se colocó una resistencia de
220Ω obteniendo una corriente de I = (5V-1.25V)/220 = 17.04mA, una vez la luz del emisor es
reflejada sobre la superficie está es captada por la base del foto-transistor y si la corriente es
suficiente, permite el paso de corriente entre el colector y el emisor funcionando como un
interruptor, que recibirá el CI MCP3008.

Fig. Circuito para sensores ópticos e infrarrojos mediante MCP3008.

En las pruebas realizadas con este circuito se comprobó que el sensor responde digitalmente, es
decir, 1 y 0 a la distancia máxima de 10mm, además el CNY70 proporciona un voltaje vs la
distancia al objeto que refleja la luz.

8
Programación
Diagrama de flujo

Datos requeridos

Velocidad por las ruedas: 19,8 cm/s


Perímetro recorrido por la rueda en una vuelta: 21,7 cm
Número de vueltas en distancia 121 cm: 5,5
Vueltas por segundo: 0,9 vueltas/s
Distancia entre ruedas: 11,5 cm

//Se colocan las librerías que se va a requerir la Raspberry.


#include <stdio.h>
#include <math.h>

//Se realiza la declaración de las variables globales y se las inicializa, así como se ejecuta wiringPi
y supone que el programa de llamada usará el esquema de numeración de pin wiringPi y a su
vez la ubicación física de pines Broadcom GPIO.
int main() {
int i,a=4;
int wi,wd;
int vdl=0,vil=0;
int L,vm;
float lw=22.0,b=11.5;

wiringPiSetup();

// Por consola se indica la distancia a desplazar y el ángulo de giro mediante los datos obtenidos
inicialmente de la mecánica del vehículo.
printf("Introduzca la distancia en cm que desea avanzar:\n");
scanf("%d",&L);
vm=(int)((float)L*16.0/lw);
printf("Se necesita girar %d pasos para llegar\n",vm);

9
// Se crea un subproceso dentro de su programa principal que se ejecuta al mismo tiempo y que
transmite las variables entre ellos de manera segura tanto para tiempo de giro de la rueda
izquierda y derecha.
piThreadCreate(der); //Función hilo tiempo rueda derecha
piThreadCreate(izq); //Función hilo tiempo rueda derecha

wi=15+a; //hacia arriba


wd=15-a; //hacia abajo

// Se crea dos pines PWM controlado por software. El rango de PWM establecido para el tiempo
de trabajo son 10ms, indicando cuando el pin se encuentra apagado en 0 y 100 completamente
encendido.
softPwmCreate(25, 0,100); //izq
softPwmCreate(28, 0,100); //der

while (vdl<vm && vil<vm){

// Se verifica que el valor esté dentro del rango y se actualiza el valor de PWM en el pin dado
de acuerdo a la velocidad asignada para trabajar en los servomotores.
softPwmWrite(25, wi);//izq
softPwmWrite(28, wd);//der
printf("i=%d\n",i);
i=i+1;
// Se procede a sincronizar la actualización de variables de los subprocesos creados y que se
ejecutando en el programa. Se asigno un identificador 0 para el subproceso de la rueda derecha
y 1 para el subproceso de la rueda izquierda, de esta forma se detendrá hasta que el primer
subproceso que ingreso quede desbloqueado.
piLock (0); vdl=vd;
piUnlock (0);
piLock (1); vil=vi;
piUnlock (1);

printf("vdl=%d vil=%d\n",vdl,vil);
delay(100);

softPwmWrite(25, 0);//izq
softPwmWrite(28, 0);//der

PARTE II. USO DE LOS SENSORES


Cálculo de la distancia recorrida

//Para estimar la distancia que ha recorrido el robot móvil se va considerar los pulsos registrados
por cada función implementada para cada encoder PI_THREAD (der) y PI_THREAD (izq)
considerando un umbral de lectura de 381, es decir que si la variable de lectura X1>381 se
considera un nivel alto mientras que si X1<381 se establece un nivel bajo, además la lectura del
sensor se lo realiza por el canal de lectura 100 para el sensor de la derecha y 101 para el sensor
de la izquierda, incluyendo un lazo de tipo FOR para sincronizar la actualización de las variables
de los subprocesos que se encuentran en ejecución y determinar cuántos pulsos se han
receptado en el proceso de lectura.
PI_THREAD (der)
{
int x1=222;

10
int c1=0,c0=0;
x1 = analogRead (100) ;
if(x1<381){
c0=0;
}
if(x1>381){
c0=1;
}else{
}
for (;;)
{
x1 = analogRead (100) ;
if(x1<281){
c1=0;
if(c1!=c0){
piLock (0);
vd=vd+1;
//printf("x1=%d vd=%d\n",x1,vd);
piUnlock (0);
}

}else{

if(x1>381){
c1=1;
if(c1!=c0){
piLock (0);
vd=vd+1;
//printf("x1=%d vd=%d\n",x1,vd);
piUnlock (0);
}
}else{
c1=c0;
}
}
c0=c1;
delay(10);
}
}

PI_THREAD (izq)
{
int x1=222;
int c1=0,c0=0;
x1 = analogRead (101) ;
if(x1<381){
c0=0;
}
if(x1>381){
c0=1;
}else{
}

for (;;)
{
x1 = analogRead (101) ;
if(x1<281){
c1=0;
if(c1!=c0){
piLock (1);
vi=vi+1;
//printf("x1=%d vi=%d\n",x1,vi);
piUnlock (1);
}
}else{

if(x1>381){
c1=1;

11
if(c1!=c0){
piLock (1);
vi=vi+1;
//printf("x1=%d vi=%d\n",x1,vi);
piUnlock (1);
}
}else{
c1=c0;
}
}
c0=c1;
delay(10);
}
}
//Se realiza la declaración de las variables y se inicializa con los datos de construcción, como
condiciones iniciales se solicita por consola la distancia a recorrer y en base a los datos
proporcionados se calculara la distancia, usando los datos recibidos por las funciones de los
encoders.

int main() {
int i,a=4;
int wi,wd;
int vdl=0,vil=0;
int L,vm;
float lw=22.0,b=11.5;

wiringPiSetup();

mcp3004Setup (100,0);
printf("Introduzca la distancia en cm que desea avanzar:\n");
scanf("%d",&L);
vm=(int)((float)L*16.0/lw);
printf("Se nesita girar %d pasos para llegar\n",vm);

piThreadCreate(der);
piThreadCreate(izq);

wi=15+a; //hacia arriba


wd=15-a; //hacia abajo

softPwmCreate(25, 0,100); //izq


softPwmCreate(28, 0,100); //der

while (vdl<vm && vil<vm){

softPwmWrite(25, wi);//izq
softPwmWrite(28, wd);//der
printf("i=%d\n",i);
i=i+1;
piLock (0);
vdl=vd;
piUnlock (0);
piLock (1);
vil=vi;
piUnlock (1);

printf("vdl=%d vil=%d\n",vdl,vil);
delay(100);

}
softPwmWrite(25, 0);//izq
softPwmWrite(28, 0);//der

12
Giro del robot
//Como condiciones iniciales se solicita por consola el ángulo en grados que se requiere girar, el
ángulo ingresado se compara para condicionar el giro de las ruedas para ángulos positivos o
ángulos negativos, además se calcula el ángulo por lo datos proporcionados inicialmente y a
partir de los pasos calculados se activan los hilos, mientras se compara en un lazo WHILE se
controla el giro de las ruedas en función del PWM asignado.

printf("Introduzca el ángulo que desea girar, grados, positivo hacia


derecha:\n");
scanf("%d",&L);
if(L>=0){
wi=15+a; //hacia arriba
wd=15; //hacia abajo
}else{
wi=15; //hacia arriba
wd=15-a; //hacia abajo
L=-L; //nos interesa su valor absoluto
}

vm=(int)(((float)L*(M_PI/180.0)*b)*16.0/lw);
printf("Se necesita girar %d pasos para girar %d grados\n",vm,L);

piLock (0);
vd=0;
vdl=vd;
piUnlock (0);

piLock (1);
vi=0;
vil=vi;
piUnlock (1);

while (vdl<vm && vil<vm){

softPwmWrite(25, wi);//izq
softPwmWrite(28, wd);//der
printf("i=%d\n",i);
i=i+1;

piLock (0);
vdl=vd;
piUnlock (0);
piLock (1);
vil=vi;
piUnlock (1);

printf("vdl=%d vil=%d\n",vdl,vil);
delay(100);

}
//printf("i=%d x1=%d\n",i,x1);
return 0;
}

//Para estimar la distancia que ha recorrido el robot móvil se va considerar los pulsos registrados
por cada función implementada para cada encoder PI_THREAD (der) y PI_THREAD (izq)
considerando un umbral de lectura de 381, es decir que si la variable de lectura X1>381 se
considera un nivel alto mientras que si X1<381 se establece un nivel bajo, además la lectura del
sensor se lo realiza por el canal de lectura 100 para el sensor de la derecha y 101 para el sensor
de la izquierda, incluyendo un lazo de tipo FOR para sincronizar la actualización de las variables
de los subprocesos que se encuentran en ejecución y determinar cuántos pulsos se han
receptado en el proceso de lectura.

13
Para el uso del sensor infrarrojo se procedió a realizar la caracterización, la cual se extrapolo en
un rango de 4 a 40cm, creando un fichero con los valores obtenidos medidos manualmente con
el rango establecido en intervalos de 1cm.

El código para la creación y registro de datos se aprecia a continuación:


#include <stdio.h>
#include <math.h>
#include <wiringPi.h>

#include "mcp3004.h"

int main() {
int x1,i;
FILE *d;
wiringPiSetup();
//wiringPiSetupGpio();

d=fopen("datos","w+");

mcp3004Setup (100,0);

for(i=0;i<10;i++){
x1 = analogRead (100) ;

printf("i=%d voltaje=%d\n",i,x1);
fprintf(d,"%d %d\n",i,x1);

getchar();
}
return 0;
}

Extrapolados los datos se genera un conjunto de valores igual a L = 731, los mismos que se
asignaran proporcionalmente en función de la distancia que sea detectada por el sensor
infrarrojo, como condiciones de fiabilidad se consideró valores superiores a los calculados se
asignara a la variable de medida m=0, de igual forma si está por debajo de los 4cm del rango
establecido.
if(x>801){m=0.0;
}else{
if(x<71){
if(x<10){
m=0.0;
}
m=40.0;
}else{
m=L[x-71];
}
} return m;
}

14
Para el control de distancia del sensor se inicializaron los parámetros para encoders y
posicionamiento, de esta forma se condiciona el inicio de coordenadas y orientación a usar.

int vd=0, vi=0; //Número total de vueltas


int vd0=0, vi0=0;

float lw=21.8, b=11.5; //perímetro rueda y distancia entre ruedas


int e=24; //pasos encoder (24)

float x=0, y=0, th=0; //Posición robot

Usando las funciones hilos y la librería mide para la lectura del sensor infrarrojo, controlamos el
posicionamiento en base a la distancia de detección, empezamos indicado por consola la
distancia que se desea avanzar, el algoritmo enviara una advertencia al detecta un objeto a una
distancia menor a 40cm,se detiene por 150ms, después avanza mientras se actualiza
continuamente la distancia detectada por el sensor hasta establecerse frente al objeto a una
distancia menor a 25cm sin embargo si el objeto ya no es detectado el vehículo continuara su
trayectoria, de lo contrario se detiene.

if(x1f<39.0 || x2f<39.0){
printf("Me choco!!\n");
softPwmWrite(25, 0);//izq
softPwmWrite(28, 0);//der
delay(150);
g=1;
while(g==1){
softPwmWrite(25, wi);//izq
softPwmWrite(28, wd);//der

x1=analogRead (102) ;
x1f=mide(x1);
x2=analogRead (103) ;
x2f=mide(x2);

while(x1f>25.0 || x2f>25.0){
printf("vdl=%d vil=%d izq=%f der=%f \n",vdl,vil,x1f,x2f);
delay(50);
x1=analogRead (102) ;
x1f=mide(x1);
x2=analogRead (103) ;
x2f=mide(x2);
}
softPwmWrite(25, 0);//izq
softPwmWrite(28, 0);//der
delay(150);

Si el objeto fue detectado y se detiene procedemos a colocarlo perpendicular a la superficie del


objeto, para reducir los errores generados en los giros, para ello se condiciona el valor medido
por los sensores.

if(x2f>x1f){
wig=15+a;
//wdg=15+a;
wdg=0;
}else{
//wig=15-a;
wig=0;
wdg=15-a;
}
Esto se realiza para (x1f>25.0 || x2f>25.0) y (x1f<25.0 || x2f<25.0) logrando detenerse frente al
objeto o avanzar sin problema en el caso de que el objeto ya no se encuentre presente.

15

Potrebbero piacerti anche