Taula de continguts:

Convertint Roomba en un Mars Rover: 5 passos
Convertint Roomba en un Mars Rover: 5 passos

Vídeo: Convertint Roomba en un Mars Rover: 5 passos

Vídeo: Convertint Roomba en un Mars Rover: 5 passos
Vídeo: How to Make a Mars Rover / Rocker bogie Robot - Stair climbing 2024, Juliol
Anonim
Convertint Roomba en un Mars Rover
Convertint Roomba en un Mars Rover

Pas 1: reuniu els vostres materials

Per completar aquest projecte, haureu de reunir els materials següents:

1 robot Roomba

1 kit Raspberry Pi

1 càmera de vídeo

Accés a MATLAB

Pas 2: baixeu les caixes d'eines Roomba per a MATLAB

Baixeu-vos les caixes d'eines Roomba per a MATLAB
Baixeu-vos les caixes d'eines Roomba per a MATLAB
Descarregueu les caixes d'eines Roomba per a MATLAB
Descarregueu les caixes d'eines Roomba per a MATLAB

Executeu el codi següent per instal·lar les caixes d'eines necessàries per completar aquest projecte.

function roombaInstall

clc;

% llista de fitxers per instal·lar

files = {'roomba.m', 'roombaSim.m', 'roombaSimGUI.m', 'roombaSimGUI.fig'};

% d'ubicació des d'on instal·lar

options = opcions web ('CertificateFilename', ''); % li diuen que ignori els requisits del certificat

server = 'https://ef.engr.utk.edu/ef230/projects/roomba-f2016/install/';

dlgTitle = 'Instal·lació / actualització de Roomba';

% mostra el propòsit i obté la confirmació

sol·licitud = {

"Aquest programa descarregarà aquests fitxers EF 230 Roomba:"

''

strjoin (fitxers, '')

''

'a aquesta carpeta:'

''

cd

''

'Vols continuar? '

};

bip;

yn = questdlg (sol·licitud, …

dlgTitle, …

"Sí", "No", "Sí");

si ~ strcmp (yn, 'Sí'), torna; final

% obtenir la llista de fitxers que existeixen

fitxers_existents = fitxers (cellfun (@exist, fitxers)> 0);

si ~ és buit (fitxers_existents)

% assegureu-vos que està realment bé substituir-los

prompt = {'Esteu substituint aquests fitxers:'

''

strjoin (fitxers_existents, '')

''

"Voleu substituir-lo?"

};

bip;

yn = questdlg (sol·licitud, …

dlgTitle, …

"Sí", "No", "Sí");

si ~ strcmp (yn, 'Sí'), torna; final

final

% descarregueu els fitxers

cnt = 0;

per a i = 1: longitud (fitxers)

f = fitxers {i};

disp (['Descarregant' f]);

provar

url = [servidor f];

websave (f, url, opcions); % d'opcions afegides per evitar errors de seguretat

cnt = cnt + 1;

atrapar

disp (['Error en descarregar' f]);

maniquí = [f '.html'];

si existeix (fictici, 'fitxer') == 2

esborrar (maniquí)

final

final

final

si cnt == longitud (fitxers)

msg = 'Instal·lació correcta';

waitfor (msgbox (msg, dlgTitle));

en cas contrari

msg = 'Error d'instal·lació: vegeu la finestra d'ordres per obtenir més detalls';

waitfor (errordlg (msg, dlgTitle));

final

end% roombaInstall

Pas 3: connecteu-vos a Roomba

Ara és hora de connectar-vos a la vostra Roomba mitjançant WiFi. Fent servir dos dits, premeu simultàniament els botons Dock i Spot per engegar o restablir el Roomba. A continuació, executeu el codi r = roomba (# del vostre Roomba) a la finestra d'ordres de MATLAB per connectar-vos al robot. Un cop hàgiu executat aquesta ordre, el vostre Roomba hauria d'estar a punt.

Pas 4: trieu com voleu controlar el vostre Roomba

Trieu com voleu controlar el vostre Roomba
Trieu com voleu controlar el vostre Roomba
Trieu com voleu controlar el vostre Roomba
Trieu com voleu controlar el vostre Roomba

Hi ha dues maneres de controlar el Roomba: de manera autònoma o mitjançant un telèfon intel·ligent com a controlador.

Si decidiu conduir el Roomba de forma autònoma, haureu d’utilitzar els tres sensors integrats: sensors de penya-segats, sensors de cops i sensors de llum.

Per utilitzar un telèfon intel·ligent, primer heu de connectar-lo a l’ordinador seguint els passos següents.

NOTA: L’ordinador i el telèfon intel·ligent han d’estar a la mateixa xarxa WiFi per connectar-se correctament.

1. Baixeu l'aplicació MATLAB des de la botiga d'aplicacions del dispositiu.

2. Escriviu "connector activat" a la finestra d'ordres i configureu una contrasenya que caldrà introduir als dos dispositius.

3. Després de fer-ho, MATLAB us proporcionarà l'adreça IP dels vostres equips. Heu d’entrar a la pàgina de configuració de l’aplicació MATLAB del telèfon intel·ligent i afegir un ordinador mitjançant l’adreça IP i la contrasenya que heu introduït anteriorment.

4. A la finestra d'ordres de l'ordinador, escriviu el codi m = mobiledev i s'hauria d'inicialitzar el telèfon intel·ligent com a controlador del Roomba.

5. L'ordinador i el telèfon intel·ligent haurien d'estar a punt per funcionar ara.

Pas 5: conduïu Roomba

Ara que teniu totes les eines necessàries per crear el vostre Mars Rover, esteu a punt per crear el vostre propi codi. A continuació us adjuntem un exemple de codi tant per a la conducció autònoma com per a la controlada per telèfon intel·ligent.

Conducció autònoma

funció Explore_modified (r)

% arguments d'entrada: 1 objecte roomba, r

% arguments de sortida: cap

% descripció:

La funció% utilitza un bucle while infinit per permetre-ho de forma autònoma

% d'exploració de l'entorn del bot.

%

% funciton també proporciona instruccions a roomba sobre què fer

% de les situacions següents: Roda (s) perd (s) en contacte amb el terra, un

% object es detecta davant o a banda i banda del bot i a

% de caiguda sobtada es detecta davant o cap als dos costats del bot.

%

% d'instruccions típiques inclouen ordres de moviment destinades a maximitzar

% d'exploració o evitar un perill detectat i ordres per comunicar-se

% d'informació sobre els descobriments dels robots (imatges), posició (gràfic), % i estat (advertència bloquejada) amb l'usuari mitjançant matlab i / o correu electrònic. Diversos

S'afegeixen% ordres de so per gaudir.

% configuració de funcions de correu electrònic

mail = '[email protected]';

password = 'EF230Roomba';

setpref ('Internet', 'SMTP_Server', 'smtp.gmail.com');

setpref ('Internet', 'E-mail', correu);

setpref ('Internet', 'SMTP_Username', correu);

setpref ('Internet', 'SMTP_Password', contrasenya);

atrezzo = java.lang. System.getProperties;

props.setProperty ('mail.smtp.starttls.enable', 'true');

props.setProperty ('mail.smtp.auth', 'true');

props.setProperty ('mail.smtp.socketFactory.class', 'javax.net.ssl. SSLSocketFactory');

props.setProperty ('mail.smtp.socketFactory.port', '465');

% r = roomba (19)

r.beep ('G2 ^^, G2 ^^, G2 ^^, G2 ^^, A2 ^^, A2 ^^, G1 ^^, E1 ^^, C2 ^^, C2 ^^, C1 ^^, C1 ^^, D1 ^^, C1 ^^, D2 ^^, E4 ^^, G2 ^^, G2 ^^, G2 ^^, G2 ^^, A2 ^^, A2 ^^, G1 ^^, E1 ^^, C2 ^^, C2 ^^, C2 ^^, E1 ^^, E1 ^^, E1 ^^, D1 ^^, C4 ^^ ');

v =.1;

reflect_datum = 2700; % establir el valor de referència dels sensors de penya-segat

lightBumper_datum = 200; % establir el valor de referència dels sensors de para-xocs de llum

pos = [0, 0]; % variable per a emmagatzematge de posicions amb dades inicialitzades

angle = 0; % estableix l'angle de referència

netangle = 0; % de desplaçament de l'angle net

i = 2; % iterador per afegir files a la variable d'emmagatzematge de posició

dist = 0;

r.setDriveVelocity (v, v); % Comença roomba avançant

tot i que és cert

Cliff = r.getCliffSensors;

Bump = r.getBumpers;

Light = r.getLightBumpers;

RandAngle = randi ([20, 60], 1); % genera 1 angle aleatori entre 20 i 60 graus. S’utilitza per evitar que el robot s’enganxi en un bucle

Què cal fer si una o més rodes perden el contacte amb el terra:

% atureu el moviment, envieu un missatge d'advertiment amb una imatge de l'entorn, % i pregunteu a l'usuari si voleu continuar o esperar ajuda

si Bump.rightWheelDrop == 1 || Bump.leftWheelDrop == 1

r.stop

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

r.beep ('F # 1 ^^, C1 ^^, F # 1 ^^, C1 ^^, F # 1 ^^, C1 ^^, F # 1 ^^, C1 ^^, F # 1 ^^, C1 ^^, F # 1 ^^, C1 ^^, F # 1 ^^, C1 ^^, F # 1 ^^, C1 ^^ ')

img = r.getImage;

imwrite (img, 'stuck.png');

%--------------------------

imfile = 'stuck.png';

posició = savepos (pos);

%---------------------------

sendmail (correu, "HELP!", "Estic encallat en un penya-segat!", {imfile, position})

list = {'Continue', 'Stop'};

idx = menu ('Què he de fer?', llista);

si idx == 2

trencar

final

% Què cal fer si es detecta un objecte davant del bot:

% parar, retrocedir, fer una foto, alertar l'usuari del descobriment

% per correu electrònic, gireu 90 graus i continueu explorant

elseif Light.leftCenter> lightBumper_datum || Light.rightCenter> lightBumper_datum || Bump.front == 1

r.stop;

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

r.moveDistance (-. 125);

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

r.beep ('A1 ^, A1 ^, A4 ^, A2 ^, G2 ^, G2 ^, G4 ^, Bb2 ^, Bb2 ^, Bb3.5 ^, G1 ^, A8 ^')

img = r.getImage;

imwrite (img, 'FrontBump.png')

%--------------------------

imfile = 'FrontBump.png';

posició = savepos (pos);

%---------------------------

sendmail (correu electrònic, 'Alerta!', 'He trobat alguna cosa!', {imfile, position})

angle = 90;

netangle = netangle + angle;

r.turnAngle (angle);

r.setDriveVelocity (v, v);

% Què cal fer si es detecta l'objecte a l'esquerra del bot:

% parar, girar cap a l'objecte, fer còpies de seguretat, fer fotos, alerta

% d'usuaris del descobriment per correu electrònic, gireu 90 graus i continueu explorant

elseif Light.leftFront> lightBumper_datum || Light.left> lightBumper_datum || Bump.left == 1

r.stop;

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

angle = 30;

netangle = netangle + angle;

r.turnAngle (angle);

r.moveDistance (-. 125);

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

r.beep ('A4 ^, A4 ^, G1 ^, E1 ^, C3.5 ^, C2 ^^, C1 ^, C1 ^, C2 ^, D2 ^, D2 ^, E8 ^')

img = r.getImage;

imwrite (img, 'LeftBump.png')

%--------------------------

imfile = 'LeftBump.png';

posició = savepos (pos);

%---------------------------

sendmail (correu electrònic, 'Alerta!', 'He trobat alguna cosa!', {imfile, position})

angle = -90;

netangle = netangle + angle;

r.turnAngle (angle);

r.setDriveVelocity (v, v);

% Què cal fer si es detecta l'objecte a la dreta del bot:

% parar, girar cap a l'objecte, fer còpies de seguretat, fer fotos, alerta

% d'usuaris del descobriment per correu electrònic, gireu 90 graus i continueu explorant

elseif Light.rightFront> lightBumper_datum || Light.right> lightBumper_datum || Bump.right == 1

r.stop;

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

angle = -30;

netangle = netangle + angle;

r.turnAngle (angle);

r.moveDistance (-. 125);

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

pausa (1,5);

r.beep ('C1 ^, C1 ^, C2 ^, D2 ^, D2 ^, C8 ^')

img = r.getImage;

imwrite (img, 'RightBump.png')

%--------------------------

imfile = 'RightBump.png';

posició = savepos (pos);

%---------------------------

sendmail (mail, 'Alert!', 'He trobat alguna cosa!', {imfile, position});

angle = 90;

netangle = netangle + angle;

r.turnAngle (angle);

r.setDriveVelocity (v, v);

% Què cal fer si es detecta un penya-segat a l'esquerra del bot:

% parar, moure cap enrere, girar a la dreta, continuar explorant

elseif Cliff.left <reflect_datum || Cliff.leftFront <reflect_datum

r.stop;

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

r.moveDistance (-. 125);

dist = r.getDistance;

pos (i, 1) = pos (i-1, 1) + dist * sind (netangle); % obtenir la coordenada x

pos (i, 2) = pos (i-1, 2) + dist * cosd (netangle); % obtenir la coordenada y

i = i + 1;

angle = -RandAngle;

netangle = netangle + angle;

r.turnAngle (angle);

r.setDriveVelocity (v, v);

% Què cal fer si es detecta un penya-segat a la dreta del bot:

% parar, moure cap enrere, girar a l'esquerra, continuar explorant

elseif Cliff.right <reflect_datum || Cliff.rightFront <reflect_datum

r.stop;

dist = r.getDistance;

pos (i, 1) = dist * sind (angle); % obtenir la coordenada x

pos (i, 2) = dist * cosd (angle); % obtenir la coordenada y

i = i + 1;

r.moveDistance (-. 125);

angle = RandAngle;

netangle = netangle + angle;

r.turnAngle (angle);

r.setDriveVelocity (v, v);

final

final

Controlador de telèfon intel·ligent

Opcions = {'Autònom', 'Control manual'}

Prompt = menu ("Com voleu controlar el rover?", Opcions)

m = mobiledev

r = roomba (19)

si Pregunta == 1

Explora (r)

en cas contrari

tot i que és cert

pausa (.5)

PhoneData = m. Orientation;

Azi = PhoneData (1);

Pitch = PhoneData (2);

Side = PhoneData (3);

si Side> 130 || Lateral <-130% si el telèfon es gira cara avall, atureu el roomba i sortiu del bucle

r. aturar-se

r.beep ("C, C, C, C")

trencar

elseif Side> 25 && Side <40% si el telèfon es gira de costat entre 25 i 40 graus, gireu a l'esquerra 5 graus

r.turnAngle (-5);

elseif Side> 40% si el telèfon es gira de costat més de 40 °, gireu a l'esquerra 45 °

r.turnAngle (-45)

elseif Side-40% si el telèfon es gira de costat entre -25 i -40 graus, gireu a la dreta 5 graus

r.turnAngle (5);

elseif Side <-40% si el telèfon es gira de costat menys de -40 °, gireu a l'esquerra 45 °

r.turnAngle (45)

final

% Si el telèfon es manté a prop de la vertical, pren una imatge i dibuixa-la

si Pitch <-60 && image <= 9

r.pip

img = r.getImage;

subtrama (3, 3, imatge)

imshow (img)

final

% avançar i retrocedir segons l'orientació frontal i posterior

si Pitch> 15 && Pitch <35% si el pitch entre 15 i 35 ° avança a poca distància

% d'obtenir dades de para-xocs lleugeres abans de moure's

litBump = r.getLightBumpers;

si litBump.leftFront> 500 || litBump.leftCenter> 500 || litBump.rightCenter> 500 || litBump.rightFront> 500% si hi ha alguna cosa davant de la sala i tocarà si avança, fa soroll i mostra el missatge

r.beep ('C ^^, F # ^, C ^^, F # ^')

altrament% move

r.moveDistance (.03);

% Obteniu dades de para-xocs després de moure-us

Bump = r.getBumpers;

si Bump.right == 1 || Bump.left == 1 || Bump.front == 1

r.beep ("A, C, E")

r.moveDistance (-. 01)

final

% obtenir dades del sensor de penya-segat

Cliff = r.getCliffSensors;

si Cliff.left> 1500 || Cliff.leftFront> 1500 || Cliff.rightFront> 1500 || Cliff.right> 1500% si alguna cosa desencadena el sensor de penya-segat, el tracten com a lava i es fan còpies de seguretat

r.beep ('C ^^, C, C ^^, C, C ^^, C, C ^^, C, C ^^, C, C ^^, C')

r.moveDistance (-. 031)

final

final

elseif Pitch> 35% si el to és superior a 35 graus avançar una distància més llarga

% d'obtenir dades de para-xocs lleugeres abans de moure's

litBump = r.getLightBumpers;

si litBump.leftFront> 15 || litBump.leftCenter> 15 || litBump.rightCenter> 15 || litBump.rightFront> 15% si hi ha alguna cosa davant de la sala i tocarà si avança, fa soroll i mostra el missatge

r.beep ('C ^^, F # ^, C ^^, F # ^')

altrament% move

r.moveDistance (.3)

% Obteniu dades de para-xocs després de moure-us

Bump = r.getBumpers;

si Bump.right == 1 || Bump.left == 1 || Bump.front == 1% si premeu alguna cosa, feu soroll, mostreu el missatge i feu una còpia de seguretat

r.beep ("A, C, E")

r.moveDistance (-. 01)

final

% obtenir dades del sensor de penya-segat després de moure's

Cliff = r.getCliffSensors;

si Cliff.left> 1500 || Cliff.leftFront> 1500 || Cliff.rightFront> 1500 || Cliff.right> 1500% si alguna cosa desencadena el sensor de penya-segat, el tracten com a lava i es fan còpies de seguretat

r.beep ('C ^^, C, C ^^, C, C ^^, C, C ^^, C, C ^^, C, C ^^, C')

r.moveDistance (-. 31)

final

final

elseif Pitch-35% si el to entre -15 i -35 ° es retrocedeix a poca distància

r.moveDistance (-. 03);

% obtenir dades del sensor de penya-segat després de moure's

Cliff = r.getCliffSensors;

si Cliff.left> 1500 || Cliff.leftFront> 1500 || Cliff.rightFront> 1500 || Cliff.right> 1500% si alguna cosa desencadena el sensor de penya-segat, el tracten com a lava i es fan còpies de seguretat

r.beep ('C ^^, C, C ^^, C, C ^^, C, C ^^, C, C ^^, C, C ^^, C')

r.moveDistance (.04)

final

elseif Pitch-60% si el to entre -35 i -60 graus retrocedeix una distància més llarga

r.moveDistance (-. 3)

% obtenir dades del sensor de penya-segat després de moure's

Cliff = r.getCliffSensors;

si Cliff.left> 1500 || Cliff.leftFront> 1500 || Cliff.rightFront> 1500 || Cliff.right> 1500% si alguna cosa desencadena el sensor del penya-segat, el tracta com a lava i es fa una còpia de seguretat

r.beep ('C ^^, C, C ^^, C, C ^^, C, C ^^, C, C ^^, C, C ^^, C')

r.moveDistance (.31)

final

final

final

final

Recomanat: