Sunteți pe pagina 1din 37

Robotul Turtlebot3 Waffle Pi

Realizat de studenta: Profesori coordonatori:

Adile-Elena NEMOIANU Dr. Ing. Claudia BOJAN-DRAGOS

Anul: 4 Dr. Ing. Alexandru-Sebastian TOPLEAN

Grupa: 4.1

Sectia: Ingineria Sistemelor

Timişoara 2022
1. Partea teoretica a proiectului

TurtleBot, care provine din „Turtle of Logo”, este conceput pentru a preda
limbajul de programare pentru computer folosind Logo. Există 3 versiuni ale
modelului TurtleBot.

TurtleBot1 constă dintr-o bază iRobot Create, un acumulator de 3.000 mAh, o


placă de alimentare TurtleBot cu giroscop, un senzor Kinect, un laptop Asus 1215N
cu un procesor dual core și un kit de montare hardware care atașează totul și
adaugă viitori senzori. Primul TurtleBot a fost creat la Willow Garage de Melonee
Wise și Tully Foote în noiembrie 2010.

TurtleBot2 constă dintr-o bază Yujin Kobuki, un acumulator de 2.200 mAh, un


senzor Kinect, un laptop Asus 1215N cu un procesor dual core, încărcător rapid,
stație de încărcare și un kit de montare hardware care atașează totul și adaugă
viitori senzori. Turtlebot2 a fost lansat în octombrie 2012.

TurtleBot3 este un robot mobil mic, accesibil, programabil, bazat pe ROS, pentru
utilizare în educație, cercetare, hobby și prototipuri de produse. TurtleBot3 adoptă
actuatorul inteligent ROBOTIS DYNAMIXEL pentru conducere.

ROBOTIS DYNAMIXEL SDK este un kit de dezvoltare software care oferă funcții
de control DYNAMIXEL folosind comunicarea de pachete.
SDK-ul DYNAMIXEL poate fi utilizat pe PC-uri, precum desktop-uri sau laptop-uri,
de asemenea, poate fi utilizat pe tablete și pe SBC-uri, precum Raspberry Pi și
UpBoards. În plus, poate fi folosit cu plăci încorporate care acceptă IDE-ul Arduino.
DYNAMIXEL utilizează comunicații TTL și RS485. Pentru a folosi computerul și
DYNAMIXEL, este recomandat sa se utilizeze ca dispozitiv de interfață
USB2DYNAMIXEL sau U2D2.
ROBOTIS DYNAMIXEL SDK acceptă toate cele trei sisteme de operare: Windows,
Linux și MacOS.
ROBOTIS DYNAMIXEL SDK acceptă diverse limbaje de programare: C, C++, C#,
Python, Java, MATLAB și LabVIEW. În plus, DYNAMIXEL SDK acceptă ROS, deci
poate fi folosit ca bibliotecă ROS folosind module C++ sau Python.
Tehnologia de bază a TurtleBot3 este SLAM, Navigare și Manipulare, ceea ce îl
face potrivit pentru roboții de serviciu la domiciliu.
TurtleBot poate rula algoritmi SLAM (localizare și mapare simultană) pentru a
construi o hartă și se poate deplasa printr-o camera. De asemenea, poate fi
controlat de la distanță de pe un laptop, joypad sau telefon inteligent bazat pe
Android.
TurtleBot poate urmări, de asemenea, picioarele unei persoane în timp ce
merge într-o cameră. De asemenea, TurtleBot3 poate fi folosit ca un manipulator
mobil capabil să manipuleze un obiect prin atașarea unui manipulator precum
OpenMANIPULATOR.

OpenMANIPULATOR are avantajul de a fi compatibil cu TurtleBot3 Waffle și


Waffle Pi. Prin această compatibilitate poate compensa lipsa de libertate și poate
avea o mai mare completitudine ca robot de serviciu cu SLAM-ul și capabilitățile de
navigare pe care le are TurtleBot3.
OpenMANIPULATOR-X RM-X52-TNM este o platformă deschisă, creata pentru
hardware si software. Majoritatea componentelor sunt încărcate ca fișiere STL,
astfel încât utilizatorii să le poată imprima cu ușurință 3D. De asemenea, permite
utilizatorilor să modifice lungimea legăturilor sau designul robotului pentru
propriile lor scopuri. OpenMANIPULATOR-X RM-X52-TNM este fabricat din seria
DYNAMIXEL-X, care este utilizată în TurtleBot 3.
OpenMANIPULATOR-X RM-X52-TNM poate fi controlat și folosind OpenCR
(Open-source Control module for ROS), placa de control utilizată în TurtleBot3.
In cazul in care utilizatorul nu are un robot real, acesta poate controla robotul
virtual, folosind simulatorul Gazebo.

Simulatorul Gazebo emulează hardware-ul robotului în software pentru a oferi


intrare către ROS.
TurtleBot 3 WafflePi de la software-ul Robotis include cod ROS pentru a rula
robotul și fișierele de configurare pentru Gazebo.
ROS poate fi instalat direct pe o stație de lucru Linux, poate fi instalat și într-un
container sau pe o mașină virtuală dedicată simulatorului:

lxc launch -p ros ubuntu:20.04 turtlebot


lxc ubuntu turtlebot
Este necesar sa se instaleze si instrumentul care ne permite să construim
software-ul TurtleBot pe stația de lucru:

sudo apt install python3-colcon-common-extensions


sudo apt install gazebo11 ros-foxy-gazebo-ros-pkgs

De asemenea, putem alege să instalam software suplimentar pentru a explora


unele dintre funcțiile ROS mai avansate. Pentru a permite robotului să
cartografieze mediul local, se poate instala Cartographer 3D SLAM pentru
localizare și cartografiere simultane. Pentru a experimenta mișcarea robotului într-
o lume reală, instalam Navigation Stack pentru ROS 2:

sudo apt install ros-foxy-cartographer


sudo apt install ros-foxy-cartographer-ros
sudo apt install ros-foxy-navigation2
sudo apt install ros-foxy-nav2-bringup

Apoi, se va instala TurtleBot prin descărcarea fișierelor sursă, compilarea și


instalarea software-ului:

sudo apt install python3-vcstool


mkdir -p ~/turtlebot3_ws/src
cd ~/turtlebot3_ws
wget https://raw.githubusercontent.com/ROBOTIS-
GIT/turtlebot3/ros2/turtlebot3.repos
vcs import src < turtlebot3.repos

Dupa ce codul sursă a fost descărcat din depozit, se compileaza folosind sintaxa

standard:

colcon build --symlink-install


Se obtine fișierul de configurare ROS pentru a adăuga executabilele:

echo 'source ~/turtlebot3_ws/install/setup.bash' >> ~/.bashrc

Dupa ce software-ul a fost instalat, trebuie configurate și două variabile de


mediu. Setam variabila GAZEBO_MODEL_PATH pentru a permite Gazebo să
găsească fișierele de definire a modelului TurtleBot si setam TURTLEBOT3_MODEL
la waffle_pi pentru a simula TurtleBot3 Waffle Pi.

Adaugam aceste linii de cod in fisierul .bashrc si rulam:

echo 'export
GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/turtlebot3_ws/src/turtlebot3/
turtlebot3_simulations/turtlebot3_gazebo/models' >> ~/.bashrc
echo 'export TURTLEBOT3_MODEL=waffle_pi' >> ~/.bashrc
source ~/.bashrc

Astfel, tot software-ul necesar a fost instalat și configurat, prin urmare urmeaza
lansarea simulatorul folosind comanda:

ros2 launch turtlebot3_gazebo empty_world.launch.py

ros2 topic list


ros2 service list
ros2 topic pub /cmd_vel geometry_msgs/Twist '{linear: {x: 1.0}}' -1
ros2 topic pub /cmd_vel geometry_msgs/Twist '{linear: {x: 0.0}}' -1
ros2 run turtlebot3_teleop teleop_keyboard
Un TurtleBot3 real este alcătuit din plăci modulare, pe care utilizatorii le pot
personaliza. El este disponibil în trei variante: Burger -de dimensiune mica-, Waffle
si Waffle Pi -de dimensiune medie-.
TurtleBot3 constă dintr-o bază, două motoare Dynamixel, un acumulator de
1.800 mAh, un LIDAR de 360 de grade, o cameră (+ cameră RealSense pentru kit
Waffle, + Camera Raspberry Pi pentru kit Waffle Pi), un SBC (calculator cu o singură
placă: Raspberry PI 3 și Intel Joule 570x) și un kit de montare hardware care
atașează totul și adaugă viitori senzori. Turtlebot3 a fost lansat în mai 2017.
2. Partea aplicativa a proiectului

Se va realiza o aplicatie folosind robotul virtual TurtleBot3 Waffle Pi si


simulatorul Gazebo, care consta in traversarea unui labirint a respectivului robot,
de la intrare, pana la iesire.

Codul folosit:

dictionaries.py

from
robot_control_class
import
RobotControl
#importa uma
classe
robotcontrol = RobotControl() #criando um objeto

lista_laser = robotcontrol.get_laser_full()

dicionario_laser = {}

for chave, objeto in enumerate(lista_laser):


dicionario_laser[chave] = objeto

for i in dicionario_laser:
print ('Posicao', i, dicionario_laser[i])
labirinto.py

import
time
from robot_control_class import RobotControl #importa uma classe
robotcontrol = RobotControl() #criando um objeto

class Robo:

def __init__(self):
print("inicializando...")
self.laser1 = robotcontrol.get_laser(360)
self.robotmove_speed = 5
self.robotmove_time = 1
self.robotturn_clockwise = "clockwise"
self.robotturn_speed = 0.8
self.robotturn_time = 1

def robotmove(self):
while self.laser1 > 1:
robotcontrol.move_straight()
self.laser1 = robotcontrol.get_laser(360)
print("distancia: ", self.laser1)

robotcontrol.stop_robot()
print("estou perto demais da parede... ")

def robotturn(self):
distancia_direita = robotcontrol.get_laser(180)
distancia_esquerda = robotcontrol.get_laser(540)
print("direita",distancia_direita, "esquerda", distancia_esquerda)
if distancia_direita > distancia_esquerda:
while self.laser1 < 1:
robotcontrol.turn(self.robotturn_clockwise, self.robotturn_speed,
self.robotturn_time)
self.laser1 = robotcontrol.get_laser(360)
print("direita: distancia: ", self.laser1)
else:
while self.laser1 < 1:
robotcontrol.turn("aclockwise", self.robotturn_speed, self.robotturn_time)
self.laser1 = robotcontrol.get_laser(360)
print("esquerda: distancia: ", self.laser1)

robotcontrol.stop_robot()
print("ja virei, bora... ")

if __name__ == '__main__':

robo = Robo()

while not robotcontrol.ctrl_c:

robo.robotmove()
robo.robotturn()

lists.py

from
robot_control_class
import
RobotControl
#importa uma
classe
robotcontrol = RobotControl() #criando um objeto

laser = robotcontrol.get_laser_full()
print ("Position: 0", laser[0])
print ("Position: 360", laser[360])
print ("Position: 719", laser[719])

pyscript1.py

from
robot_control_class
import
RobotControl
#importa uma
classe
robotcontrol = RobotControl() #criando um objeto

a = robotcontrol.get_laser(330)

print ("The laser value received is: ", a)

robot_control_class.py

#!/usr/bin/env
python

import rospy
from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan
import time

class RobotControl():

def __init__(self):
rospy.init_node('robot_control_node', anonymous=True)
self.vel_publisher = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
self.laser_subscriber = rospy.Subscriber(
'/kobuki/laser/scan', LaserScan, self.laser_callback)
self.cmd = Twist()
self.laser_msg = LaserScan()
self.ctrl_c = False
self.rate = rospy.Rate(1)
rospy.on_shutdown(self.shutdownhook)

def publish_once_in_cmd_vel(self):
"""
This is because publishing in topics sometimes fails the first time you
publish.
In continuos publishing systems there is no big deal but in systems
that publish only
once it IS very important.
"""
while not self.ctrl_c:
connections = self.vel_publisher.get_num_connections()
if connections > 0:
self.vel_publisher.publish(self.cmd)
#rospy.loginfo("Cmd Published")
break
else:
self.rate.sleep()

def shutdownhook(self):
# works better than the rospy.is_shutdown()
self.ctrl_c = True

def laser_callback(self, msg):


self.laser_msg = msg

def get_laser(self, pos):


time.sleep(1)
return self.laser_msg.ranges[pos]
def get_front_laser(self):
time.sleep(1)
return self.laser_msg.ranges[360]

def get_laser_full(self):
time.sleep(1)
return self.laser_msg.ranges

def stop_robot(self):
#rospy.loginfo("shutdown time! Stop the robot")
self.cmd.linear.x = 0.0
self.cmd.angular.z = 0.0
self.publish_once_in_cmd_vel()

def move_straight(self):

# Initilize velocities
self.cmd.linear.x = 0.5
self.cmd.linear.y = 0
self.cmd.linear.z = 0
self.cmd.angular.x = 0
self.cmd.angular.y = 0
self.cmd.angular.z = 0

# Publish the velocity


self.publish_once_in_cmd_vel()

def move_straight_time(self, motion, speed, time):

# Initilize velocities
self.cmd.linear.y = 0
self.cmd.linear.z = 0
self.cmd.angular.x = 0
self.cmd.angular.y = 0
self.cmd.angular.z = 0
if motion == "forward":
self.cmd.linear.x = speed
elif motion == "backward":
self.cmd.linear.x = - speed

i=0
# loop to publish the velocity estimate, current_distance = velocity *
(t1 - t0)
while (i <= time):

# Publish the velocity


self.vel_publisher.publish(self.cmd)
i += 1
self.rate.sleep()

# set velocity to zero to stop the robot


self.stop_robot()

s = "Moved robot " + motion + " for " + str(time) + " seconds"
return s

def turn(self, clockwise, speed, time):

# Initilize velocities
self.cmd.linear.x = 0
self.cmd.linear.y = 0
self.cmd.linear.z = 0
self.cmd.angular.x = 0
self.cmd.angular.y = 0

if clockwise == "clockwise":
self.cmd.angular.z = -speed
else:
self.cmd.angular.z = speed

i=0
# loop to publish the velocity estimate, current_distance = velocity *
(t1 - t0)
while (i <= time):

# Publish the velocity


self.vel_publisher.publish(self.cmd)
i += 1
self.rate.sleep()

# set velocity to zero to stop the robot


self.stop_robot()

s = "Turned robot " + clockwise + " for " + str(time) + " seconds"
return s

if __name__ == '__main__':
#rospy.init_node('robot_control_node', anonymous=True)
robotcontrol_object = RobotControl()
try:
robotcontrol_object.move_straight()

except rospy.ROSInterruptException:
pass

test_for.py

#Exercise
2.4
#arnaldo Jr
from robot_control_class import RobotControl #importa uma classe
robotcontrol = RobotControl() #criando um objeto

laser = robotcontrol.get_laser_full()
#laser = [50, 100000, 3]
lower_value = 10000
for value in laser:
#print(value)
if value < lower_value:
lower_value = value
print("The lower_value is: ",lower_value)

test_functions.py

#Exercise
3,3
#Arnaldo Jr
import time
from robot_control_class import RobotControl #importa uma classe
robotcontrol = RobotControl() #criando um objeto

def robotmove(a,b,c):
# print('executando acao 1...',a,b,c)
resultado = robotcontrol.move_straight_time(a,b,c)
print(resultado)

def robotturn(a,b,c):
# print('executando acao 2...',+a,+b,+c)
resultado = robotcontrol.turn(a,b,c)
print(resultado)
fim = "nao"
while fim != "sim":
a = raw_input('direcao: forward ou backward ')
b = input('velocidade: m/s ')
c = input('tempo: seg ')
robotmove(a,b,c)
print('funcao turn')
d = raw_input('clockwise: ')
b = input('velocidade: m/s ')
c = input('tempo: seg ')
robotturn(d,b,c)
fim = raw_input("finalizado?")

test_if.py

#Exercise
2.1
#arnaldo jr
from robot_control_class import RobotControl #importa uma classe
robotcontrol = RobotControl() #criando um objeto

laser = robotcontrol.get_laser(360)
print(laser)

if laser <= 1:
robotcontrol.stop_robot()

else:
robotcontrol.move_straight()

print_reading()

test_input.py

from
robot_control_class
import
RobotControl
#importa uma
classe
robotcontrol = RobotControl() #criando um objeto

position = input("What's the angle position? ")

laser1 = robotcontrol.get_laser(position)

print ("The laser value received is: ", laser1)

test_oop.py

#!/usr/bin/env
python
#Exercise 4
#Arnaldo Jr

import time
from robot_control_class import RobotControl #importa uma classe
robotcontrol = RobotControl() #criando um objeto

class Robo:

def __init__(self):
print("inicializando...")
self.robotmove_motion = "forward"
self.robotmove_speed = 5
self.robotmove_time = 1
self.robotturn_clockwise = "clockwise"
self.robotturn_speed = 6
self.robotturn_time = 2

def robotmove(self):
resultado =
robotcontrol.move_straight_time(self.robotmove_motion,
self.robotmove_speed, self.robotmove_time)
print(resultado)

def robotturn(self):
resultado = robotcontrol.turn(self.robotturn_clockwise,
self.robotturn_speed, self.robotturn_time)
print(resultado)

if __name__ == '__main__':
robo = Robo()
robo.robotmove()
robo.robotturn()
robo.robotmove()

test_return.py

#Exercise
3,1
#Arnaldo Jr
import time
from robot_control_class import RobotControl #importa uma classe
robotcontrol = RobotControl() #criando um objeto

def robotmove(a):
robotcontrol.move_straight()
time.sleep(a)
robotcontrol.stop_robot()
print('Forneca 3 valores entre 0 e 719.')
value = [0,1,2]
value[0] = input('valor 1:')
value[1] = input('valor 2:')
value[2] = input('valor 3:')
print(value)

#robotmove(5)
laser1 = robotcontrol.get_laser(360)
print(laser1)

test_sleep.py

#Exercise
3,1
#Arnaldo Jr
import time
from robot_control_class import RobotControl #importa uma classe
robotcontrol = RobotControl() #criando um objeto

def robotmove(a):
robotcontrol.move_straight()
time.sleep(a)
robotcontrol.stop_robot()

robotmove(5)

test_while.py

#Exercise
3,1
#Arnaldo Jr
import time
from robot_control_class import RobotControl #importa uma classe
robotcontrol = RobotControl() #criando um objeto
laser1 = robotcontrol.get_laser(360)

while laser1 > 1:


robotcontrol.move_straight()
laser1 = robotcontrol.get_laser(360)
print("distancia: ", laser1)

robotcontrol.stop_robot()
print("estou demais da parede: ")

variables.py

from
robot_control_class
import
RobotControl
#importa uma
classe
robotcontrol = RobotControl() #criando um objeto

laser1 = robotcontrol.get_laser(360)

print ("The laser1 value received is: ", laser1)

laser2 = robotcontrol.get_laser(330)

print ("The laser2 value received is: ", laser2)

laser2 = robotcontrol.get_laser(370)

print ("The laser2 value received is: ", laser2)


3. Dupa rularea codului se obtin urmatoarele rezultatele in
simulator
4. Concluzii

Robotul TurtleBot3 Waffle Pi de la Robotis, fiind cea mai recenta versiune


TurtleBot si mai mare decat Burger, este puternic pentru explorarea ROS (Robot
Operating System), este o versiune extinsă cu o sarcină utilă mare, are senzori
suplimentari, este programabil, modular si compact si realizeaza calcule mai bune
decat versiunile sale anterioare.
5. Bibliografie

1) https://www.turtlebot.com/about/
2) https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/overview/
3) https://emanual.robotis.com/docs/en/platform/openmanipulator_x/overview/
4) http://wiki.ros.org/cartographer
5) https://www.youtube.com/watch?v=g7RSJcYW_qA&t=598s
6) https://ubuntu.com/blog/simulate-the-turtlebot3
7) https://github.com/arnaldojr/Python-3-for-Robotics
8) https://www.youtube.com/watch?v=5ADdIPpZ2pA
9) https://app.theconstructsim.com/#/

S-ar putea să vă placă și